Promise 是什么

一个"将来会有值"的对象——三种状态:pending / fulfilled / rejected,一旦转换不可逆。

const p = new Promise((resolve, reject) => {
    setTimeout(() => resolve('done'), 1000);
});

p.then(value => console.log(value));        // 1 秒后输出 'done'

三个核心方法

p.then(onFulfilled)                          // 成功时
p.then(onFulfilled, onRejected)              // 同时处理
p.catch(onRejected)                          // 失败时(语法糖 = .then(null, fn))
p.finally(onFinally)                          // 不管成败都跑

链式:

fetch('/api/user')
    .then(r => r.json())
    .then(user => fetch(`/api/posts/${user.id}`))
    .then(r => r.json())
    .then(posts => console.log(posts))
    .catch(err => console.error(err));

直接创建

Promise.resolve(42)                          // 已成功
Promise.reject(new Error('bad'))             // 已失败
Promise.resolve(somePromise)                 // 透传

并行:Promise.all

const [user, posts, comments] = await Promise.all([
    fetch('/api/user').then(r => r.json()),
    fetch('/api/posts').then(r => r.json()),
    fetch('/api/comments').then(r => r.json()),
]);

特点:

  • 全部成功 → 返回数组
  • 任一失败 → 整个 reject

适合"全要"场景。

容错并行:Promise.allSettled

const results = await Promise.allSettled([fn1(), fn2(), fn3()]);

for (const r of results) {
    if (r.status === 'fulfilled') {
        console.log(r.value);
    } else {
        console.error(r.reason);
    }
}

特点:

  • 永远不 reject
  • 每个结果是 {status, value | reason} 对象
  • 适合"尽量都试,部分失败可接受"场景

第一个:Promise.race

// 添加超时
const result = await Promise.race([
    fetch('/api/slow'),
    new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 5000)),
]);

第一个 settled(无论成功失败)就返回它。

第一个成功:Promise.any(Node 15+)

const result = await Promise.any([
    fetch('https://primary-server'),
    fetch('https://backup-server-1'),
    fetch('https://backup-server-2'),
]);
// 哪个先成功用哪个;全失败 → AggregateError

适合"主备 fallback"场景。

4 种聚合方法对比

方法 何时 resolve 何时 reject
all 全部成功 任一失败
allSettled 全部完成(不管成败) 永不
race 第一个完成 第一个失败
any 第一个成功 全部失败

链式错误处理

fetch('/api')
    .then(r => r.json())           // 这一步出错
    .then(data => processData(data))
    .catch(err => {
        // 上面任何 then 出错都到这
        console.error(err);
    });

catch 接住链上任何位置的错误——不需要每个 then 都包 try。

链式 → return 链下去

// ❌ 失去链
fetch('/a').then(r => {
    fetch('/b').then(r => console.log(r));
});

// ✓ return 给链
fetch('/a')
    .then(r => fetch('/b'))
    .then(r => console.log(r));

返回值在下一个 then 里能拿到。

把 Promise 转回调(极少用)

const callback = (err, val) => { ... };
somePromise.then(val => callback(null, val), err => callback(err));

现代姿势:基本不直接写 .then 了

// .then 链
fetch('/api')
    .then(r => r.json())
    .then(data => processData(data))
    .catch(handleError);

// async/await(下一篇)
try {
    const r = await fetch('/api');
    const data = await r.json();
    await processData(data);
} catch (err) {
    handleError(err);
}

下一篇细讲 async/await。

  • 忘加 catch → unhandled rejection → 进程级警告
  • Promise.all 失败 → 其他 Promise 仍在跑(没有自动取消
  • .then(fn) 里的 fn 不 return → 下一个 then 拿到 undefined
  • Promise 链里 同步抛错 也会被 catch 接到

下一篇:async / await。