Node.js Promise

三种状态、链式调用、四个组合器、以及几个常见误区。

Intermediate
Key PointsPromise 只有 pending / fulfilled / rejected 三态,一旦定态就不可改。

三态

JavaScript
const p = new Promise((resolve, reject) => {
  const ok = Math.random() > 0.5;
  setTimeout(() => (ok ? resolve('成功') : reject(new Error('失败'))), 100);
});

p.then((v) => console.log('fulfilled:', v))
 .catch((e) => console.log('rejected:', e.message))
 .finally(() => console.log('不管成败都执行'));
Output
fulfilled: 成功
不管成败都执行

链式调用

JavaScript
Promise.resolve(2)
  .then((n) => n * 3)          // 6
  .then((n) => n + 1)          // 7
  .then((n) => {
    if (n > 5) throw new Error('太大了');
    return n;
  })
  .catch((e) => {
    console.log('捕获:', e.message);
    return 0;                   // catch 之后链还能继续
  })
  .then((n) => console.log('继续:', n));
Output
捕获: 太大了
继续: 0

.then returns a new Promise, which is why chaining works. So does .catch — it catches errors from every earlier link and returns a normal value so the chain resumes.

四个组合器

APIBehaviourFails when
Promise.all全部成功才成功,结果按顺序任意一个 reject
Promise.allSettled等全部结束,返回状态数组从不失败
Promise.race第一个定态的说了算第一个是 reject
Promise.any第一个成功的说了算全部 reject
JavaScript
const ok = (v, ms) => new Promise((r) => setTimeout(() => r(v), ms));
const bad = (ms) => new Promise((_, j) => setTimeout(() => j(new Error('boom')), ms));

const all = await Promise.all([ok('a', 10), ok('b', 20)]);
console.log(all);                       // [ 'a', 'b' ]

const settled = await Promise.allSettled([ok('a', 10), bad(20)]);
console.log(settled.map((s) => s.status));   // [ 'fulfilled', 'rejected' ]

const race = await Promise.race([ok('fast', 10), ok('slow', 50)]);
console.log(race);                      // fast

const any = await Promise.any([bad(10), ok('winner', 30)]);
console.log(any);                       // winner
Output
[ 'a', 'b' ]
[ 'fulfilled', 'rejected' ]
fast
winner

三个误区

  • Promise 会立即执行 —— new Promise(fn) 里 fn 是同步跑的
  • **.then 里 return 一个 Promise 会自动展开** —— 不用手动 .then 嵌套
  • 忘了 return 会断链 —— 箭头函数用花括号时必须显式 return
When one promise in Promise.all fails, the others are not cancelled — they keep running and their results are discarded. For real cancellation, use AbortController.

Friends & Partners