JavaScript Promise 完全指南:从基础到进阶

一、Promise 构造函数基础

1.1 基本语法结构

var my_promise = new Promise(function(resolve, reject) {
    // 执行器函数
    if (条件) {
        resolve('成功值');
    } else {
        reject('失败值');
    }
});

1.2 执行器函数(Executor Function)

  • function(resolve, reject)匿名函数,也称为执行器函数
  • 该函数有两个参数:resolvereject
  • 关键特性:执行器函数在 new Promise()立即同步执行

1.3 resolve 和 reject 参数详解

  • 本质resolvereject函数参数(不是属性或方法)
  • 来源:由 JavaScript 引擎自动创建并传递给执行器函数
  • 作用

    • resolve(value):将 Promise 状态改为 fulfilled,并传递成功值
    • reject(reason):将 Promise 状态改为 rejected,并传递失败原因

二、Promise 的三种状态

状态英文名说明
等待中pendingPromise 的初始状态
已成功fulfilled调用 resolve() 后的状态
已失败rejected调用 reject() 后的状态

⚠️ 注意:Promise 状态一旦改变(从 pendingfulfilledrejected),就不可逆转


三、return 语句的重要性

3.1 为什么需要 return

function createPromise() {
    return new Promise((resolve, reject) => {
        // 执行器函数内容
    });
}
  • 必须写 return:将创建的 Promise 对象返回给外部
  • 不写 return:Promise 内部逻辑仍然执行,但外部无法获得 Promise 对象
  • 🚫 结果:无法调用 .then().catch() 方法

3.2 执行时机说明

my_obj = createPromise(); // 此时执行器函数立即执行
  • 执行器函数在 new Promise()立即执行(同步)
  • 不需要调用 my_obj() 来触发执行器函数
  • Promise 对象创建完成后返回给 my_obj

四、then 方法详解

4.1 基本用法

obj.then(result => console.log(result))

4.2 语法分析

  • then() 方法接受一个函数作为参数
  • result => console.log(result)箭头函数(匿名函数)

    • 参数:result
    • 函数体:console.log(result)

4.3 工作原理

  1. Promise 状态变为 fulfilled
  2. then 方法检测到状态变化
  3. 自动调用传入的回调函数
  4. 将 Promise 的成功值作为参数传递给回调函数

4.4 等价写法

// 箭头函数
obj.then(result => console.log(result))

// 传统函数
obj.then(function(result) {
    console.log(result);
})

// 命名函数
function handleResult(result) {
    console.log(result);
}
obj.then(handleResult)

五、Promise 静态方法

5.1 构造函数 vs 静态方法对比

方法是否有执行器函数用途
new Promise()✅ 有创建可控制状态的 Promise
Promise.resolve()❌ 没有直接创建成功状态的 Promise
Promise.reject()❌ 没有直接创建失败状态的 Promise

5.2 静态方法列表

单个 Promise 创建
  • Promise.resolve(value):直接创建 fulfilled 状态的 Promise
  • Promise.reject(reason):直接创建 rejected 状态的 Promise
多个 Promise 处理
  • Promise.all([p1, p2, p3]):等待所有成功,任一失败则整体失败
  • Promise.race([p1, p2, p3]):返回最先完成的 Promise 结果
  • Promise.any([p1, p2, p3]):等待第一个成功,全部失败才整体失败
  • Promise.allSettled([p1, p2, p3]):等待所有完成,返回所有结果

5.3 静态方法存在的意义

简化常见操作
// 繁琐写法
new Promise(resolve => resolve('缓存数据'));

// 简洁写法  
Promise.resolve('缓存数据');
解决复杂异步协调
  • 并发控制all, race, any, allSettled
  • 超时处理race 配合 setTimeout
  • 容错机制any 提供多个备选方案
  • 批量处理allSettled 处理批量操作结果

六、完整示例分析

function simple_promise() {
    var my_promise = new Promise(function(resolve, reject) {
        run_result = true;
        if (run_result) {
            resolve('运行成功');
        } else {
            reject('运行失败');
        }
    });
    return my_promise;
}

obj = simple_promise();
obj.then(result => console.log(result))
   .catch(reject => console.log(reject));

执行流程

  1. 调用 simple_promise() 函数
  2. 执行 new Promise(),执行器函数立即运行
  3. 条件判断,调用 resolve('运行成功')
  4. Promise 状态变为 fulfilled
  5. 返回 Promise 对象给 obj
  6. .then() 注册成功回调函数
  7. 由于 Promise 已经是成功状态,立即执行回调
  8. 输出运行成功

七、关键理解要点

📌 核心概念

  1. 执行器函数是匿名函数,在 Promise 创建时立即执行
  2. resolve/reject 是函数参数,由 JS 引擎提供,用于改变 Promise 状态
  3. resolve() 的参数不是返回值,而是传递给 .then() 的值
  4. return 必不可少,用于将 Promise 对象暴露给外部
  5. 静态方法简化操作,解决复杂异步场景的协调问题
  6. then 方法注册回调,Promise 状态改变时自动执行

🎯 最佳实践

// ✅ 推荐写法:清晰的错误处理
function fetchData() {
    return new Promise((resolve, reject) => {
        // 异步操作
        setTimeout(() => {
            const success = Math.random() > 0.5;
            if (success) {
                resolve({ data: '数据' });
            } else {
                reject(new Error('获取失败'));
            }
        }, 1000);
    });
}

// 链式调用
fetchData()
    .then(result => {
        console.log('成功:', result);
        return result.data;
    })
    .catch(error => {
        console.error('失败:', error.message);
    })
    .finally(() => {
        console.log('操作完成');
    });

八、常见误区与陷阱

❌ 错误示例 1:忘记 return

function bad_promise() {
    new Promise((resolve, reject) => {
        resolve('数据');
    });
    // 忘记 return,外部无法获取 Promise
}

bad_promise().then(data => console.log(data)); // TypeError

❌ 错误示例 2:误解 resolve() 为返回值

function bad_example() {
    return new Promise((resolve, reject) => {
        const result = resolve('值'); // resolve 没有返回值
        console.log(result); // undefined
    });
}

✅ 正确理解

  • resolve() 只是改变状态传递值.then()
  • 不要将 resolve() 当作 return 使用

九、进阶应用场景

场景 1:并发请求控制

const promises = [
    fetch('/api/user'),
    fetch('/api/posts'),
    fetch('/api/comments')
];

Promise.all(promises)
    .then(responses => Promise.all(responses.map(r => r.json())))
    .then(data => console.log('所有数据:', data))
    .catch(error => console.error('某个请求失败:', error));

场景 2:超时控制

function timeoutPromise(promise, timeout) {
    return Promise.race([
        promise,
        new Promise((_, reject) => 
            setTimeout(() => reject(new Error('超时')), timeout)
        )
    ]);
}

timeoutPromise(fetch('/api/data'), 3000)
    .then(data => console.log(data))
    .catch(error => console.error(error.message));

场景 3:容错处理

const servers = [
    fetch('https://server1.com/api'),
    fetch('https://server2.com/api'),
    fetch('https://server3.com/api')
];

Promise.any(servers)
    .then(response => console.log('第一个成功的服务器响应:', response))
    .catch(error => console.error('所有服务器都失败了'));

十、总结

Promise 是 JavaScript 异步编程的核心机制,掌握以下要点:

✅ 理解执行器函数的立即执行特性
✅ 掌握 resolve/reject参数传递机制
✅ 熟练使用 .then()/.catch()/.finally() 链式调用
✅ 善用静态方法处理复杂异步场景
✅ 注意错误处理状态管理

💡 提示:Promise 是 async/await 的基础,深入理解 Promise 有助于更好地使用现代异步语法。

参考资源


普郎特
18 声望3 粉丝