Node.js Promise
三种状态、链式调用、四个组合器、以及几个常见误区。
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.
四个组合器
| API | Behaviour | Fails 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); // winnerOutput
[ '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.三态
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 返回的是新的 Promise,所以能一直链下去。.catch 也是——它捕获前面所有环节的错误,并返回一个正常值让链恢复。
四个组合器
| API | 行为 | 失败条件 |
|---|---|---|
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); // winnerOutput
[ 'a', 'b' ]
[ 'fulfilled', 'rejected' ]
fast
winner三个误区
- Promise 会立即执行 ——
new Promise(fn)里fn是同步跑的 - **
.then里 return 一个 Promise 会自动展开** —— 不用手动.then嵌套 - 忘了 return 会断链 —— 箭头函数用花括号时必须显式
return
Promise.all 里一个失败,其余 Promise 并不会被取消,它们继续跑完只是结果被丢弃。要真正取消,用 AbortController。