Promise
[TOC]
索引
构造方法:
- new Promise():
(executor)
,ES2015,用于创建一个 Promise 的实例对象。
方法:
- promise.then():
(onFulfilled?, onRejected?)
,ES2015,用于接收当状态变成fulfilled
或rejected
时执行的回调函数。 - promise.catch():
(onRejected)
,ES2015,是 Promise 链式调用中的错误处理方法,用于捕获 Promise 链中发生的任何错误或拒绝。 - promise.finally():
(onFinally)
,ES2018,用于指定一个无论 Promise 最终状态如何(fulfilled 或 rejected)都会执行的回调函数。
静态方法:
- Promise.resolve():
(value)
,ES2015,用于快速创建一个已解决(fulfilled)的 Promise 对象。提供了一种将值转换为 Promise 的标准方式。 - Promise.reject():
(reason)
,ES2015,用于立即创建一个已拒绝(rejected)状态的 Promise 对象。它提供了一种快速失败机制,在异步流程中直接抛出错误或拒绝信号。 - Promise.all():
(iterable)
,ES2015,用于并行处理多个 Promise,当所有 Promise 都成功时返回成功结果,当任意一个 Promise 失败时立即返回失败。 - Promise.allsettled():
(iterable)
,ES2020,用于等待所有 Promise 完成(无论成功或失败),并返回每个 Promise 的最终状态和结果。不会因某个 Promise 失败而提前终止。 - Promise.race():
(iterable)
,ES2015,用于获取第一个完成的 Promise 结果(无论成功或失败)。 - Promise.any():
(iterable)
,ES2021,用于获取第一个成功的 Promise 结果。当所有 Promise 都失败时,它会返回一个包含所有错误信息的 AggregateError。 - Promise.try():
(executor)
,ES2025,用于统一处理 Promise 链中的同步错误和异步错误。 - Promise.withResolvers():
()
,ES2024,
Promise
构造方法
new Promise()@
new Promise():(executor)
,ES2015,用于创建一个 Promise 的实例对象。
executor:
(resolve,reject)=>void
,一个同步立即执行的处理业务逻辑的回调函数,有两个自动注入的回调参数:resolve:
function
,调用后 Promise 状态变为 fulfilled(成功),并执行 then 方法中的回调。reject:
function
,调用后 Promise 状态变为 rejected(失败),并执行 catch 方法中的回调。
返回:
promise:
Promise
,返回一个新创建的Promise
对象。
基本示例:
Promise 完整生命周期:
js// 1. 创建 Promise const orderPizza = new Promise((resolve, reject) => { console.log("厨房开始制作..."); // 同步执行 // 模拟异步操作 setTimeout(() => { const isSuccess = Math.random() > 0.3; isSuccess ? resolve("🍕 披萨做好了!") : reject("🔥 烤箱坏了!"); }, 2000); }); // 2. 使用 Promise orderPizza .then(pizza => { console.log(`成功:${pizza}`); return "开吃!"; // 传递给下一个 then }) .then(message => console.log(message)) .catch(error => console.error(`失败:${error}`)) .finally(() => console.log("--- 流程结束 ---")); /* 可能输出: 厨房开始制作... 成功:🍕 披萨做好了! 开吃! --- 流程结束 --- 或: 厨房开始制作... 失败:🔥 烤箱坏了! --- 流程结束 --- */
核心特性:
立即执行:
executor
在 Promise 创建时立即同步执行jsconsole.log('开始'); const p = new Promise(() => { console.log('executor 执行'); }); console.log('结束'); // 输出顺序: // 开始 → executor 执行 → 结束
错误抛出:在
executor
中抛出/出现错误等同于调用reject()
jsnew Promise(() => { throw new Error('出错了!'); // 等同于 reject nonExistentFunction(); // 自动触发 reject }).catch(err => console.log(err)); // 捕获错误
resolve/reject 特性:
单向不可逆:状态一旦确定不能更改。只有第一次调用生效,后续调用无效。
jsnew Promise((resolve, reject) => { resolve('成功'); // 生效 reject('失败'); // 被忽略 resolve('再次尝试'); // 被忽略 });
参数传递:参数会传递给后续的
.then()
或.catch()
jsnew Promise(resolve => resolve({ data: [1, 2, 3] })) .then(result => console.log(result.data)); // [1, 2, 3]
resolve 参数类型:不同的参数类型会有不同的处理:
普通值(包括原始类型、对象、数组等):
当前 Promise 状态变成 fulfilled。
另一个 Promise:
当前 Promise 的状态会"跟随"该新 Promise 的状态
thenable 对象(实现了 then() 方法的对象):
会自动执行该 then 方法,并且根据 then 方法的结果来决定当前 Promise 的状态
状态查看:可通过
console.dir(promise)
查看 Promise 的当前状态
方法
then()@
promise.then():(onFulfilled?, onRejected?)
,ES2015,用于接收当状态变成 fulfilled
或 rejected
时执行的回调函数。
onFulfilled?:
res=>void
,当 Promise 解决(fulfilled)时调用的函数onRejected?:
err=>void
,当 Promise 拒绝(rejected)时调用的函数返回:
promise:
Promise
,返回一个新的 Promise 对象。其状态取决于回调函数的返回值类型。
核心特性:
异步执行:
.then()
的回调参数总是异步执行(微任务队列)jsconsole.log('开始'); Promise.resolve() .then(() => console.log('微任务1')) .then(() => console.log('微任务2')); console.log('结束'); /* 输出顺序: 开始 结束 微任务1 微任务2 */
错误处理流程:
错误会沿着 Promise 链传播,直到被捕获:
jsPromise.resolve() .then(() => { throw new Error('错误1'); }) .then(() => { console.log('不会执行'); }) .then(null, err => { console.error('捕获:', err.message); // '错误1' throw new Error('错误2'); }) .catch(err => { console.error('最终捕获:', err.message); // '错误2' });
多次调用:
一个 promsie 对象的 then 方法可以被多次调用,每次调用都可以传入对应的 fulfilled 回调,当 Promise 状态变成 fulfilled时这些回调都会被执行。
jsconst promise = new Promise((resolve, reject) => { resolve() // reject() }) promise.then(res => console.log('第一次调用', res)) promise.then(res => console.log('第二次调用', res)) promise.then(res => console.log('第三次调用', res))
链式调用:then 方法支持链式调用,因为它会返回一个 Promise
jsfunction getUser(id) { return fetch(`/users/${id}`) .then(response => response.json()); } function getOrders(userId) { return fetch(`/users/${userId}/orders`) .then(response => response.json()); } getUser(123) .then(user => { console.log('用户:', user); return getOrders(user.id); }) .then(orders => { console.log('订单:', orders); }) .catch(error => { console.error('请求失败:', error); });
进阶示例:
错误恢复:
jsfetchPrimaryData() .then(processData) .catch(primaryError => { console.warn('主数据源失败:', primaryError); return fetchFallbackData(); // 尝试备用源 }) .then(processData) .catch(finalError => { console.error('所有数据源失败:', finalError); return getCachedData(); // 返回缓存 }) .then(data => { renderUI(data); });
catch()@
promise.catch():(onRejected)
,ES2015,是 Promise 链式调用中的错误处理方法,用于捕获 Promise 链中发生的任何错误或拒绝。
onRejected:
err=>any
,当 Promise 被拒绝(rejected)时调用的函数。可以返回:普通值:会使新 Promise 以该值解决(fulfilled)。
Promise:新 Promise 将跟随该 Promise 的状态。
抛出错误:新 Promise 将以该错误拒绝(rejected)。
返回:
promise:
Promise
,返回一个新的 Promise 对象,其状态取决于 onRejected 函数的行为:- 普通值(包括原始类型、对象、数组等):当前 Promise 状态变成 fulfilled。
- 另一个 Promise:当前 Promise 的状态会"跟随"该新 Promise 的状态
- thenable 对象(实现了 then() 方法的对象):会自动执行该 then 方法,并且根据 then 方法的结果来决定当前 Promise 的状态
- 抛出错误:新 Promise 以该错误拒绝(rejected)
基本示例:
基本使用:
jsPromise.reject(new Error('操作失败')) .catch(error => { console.error('捕获错误:', error.message); // "操作失败" return '恢复值'; // 返回普通值 }) .then(value => { console.log('恢复后的值:', value); // "恢复值" });
核心特性:
本质:语法糖
catch
方法本质上是then
方法的语法糖:jspromise.catch(onRejected); // 等价于: promise.then(undefined, onRejected);
错误处理机制:
捕获链中任意位置的错误:
jsPromise.resolve() .then(() => { throw new Error('错误1'); }) .then(() => { console.log('不会执行'); }) .catch(error => { console.error('捕获错误1:', error.message); // "错误1" throw new Error('错误2'); }) .catch(error => { console.error('捕获错误2:', error.message); // "错误2" });
只能捕获前面的错误:
前面抛出的错误会被最近的
catch
捕获jsPromise.resolve() .catch(error => console.log('不会执行')) // 没有前面的错误 .then(() => { throw new Error('发生在捕获之后'); }) .catch(error => console.log('捕获:', error.message)); // "发生在捕获之后"
未捕获的拒绝:
如果错误没有被任何
catch
捕获,会导致"未处理的拒绝"(unhandled rejection):js// 浏览器控制台会显示警告 new Promise((_, reject) => reject('未处理的错误'));
与 then 的第二个参数区别:
catch
:能处理整个链的错误then的第二个参数
: 只能处理当前 promise 的错误
js// 使用 then 的第二个参数 promise.then( successHandler, errorHandler // 只能处理当前 promise 的错误 ); // 使用 catch promise .then(successHandler) .catch(errorHandler); // 能处理整个链的错误
多次调用:
一个 promsie 对象的 catch方法可以被多次调用,每次调用都可以传入对应的 rejected 回调,当 Promise 状态变成 rejected 时这些回调都会被执行。
jsconst promise = new Promise((resolve, reject) => { // resolve() reject() }) promise.catch(err => console.log('第一次捕获错误:', err)) promise.catch(err => console.log('第二次捕获错误:', err)) promise.catch(err => console.log('第三次捕获错误:', err))
链式调用:catch方法支持链式调用,因为它会返回一个 Promise
进阶示例:
在 async/await 中的等效形式:
js// .catch 形式 function example() { return fetchData() .then(process) .catch(handleError); } // async/await 等效 async function exampleAsync() { try { const data = await fetchData(); return process(data); } catch (error) { return handleError(error); } }
错误类型检查:使用
instanceof
检查错误类型jsfetchData() .catch(error => { if (error instanceof TypeError) { // 处理类型错误 } else { // 其他错误 } });
重新抛出有意义错误:
jsvalidateInput(input) .catch(error => { // 添加上下文信息 throw new ValidationError('输入验证失败', { cause: error }); }) .catch(error => { console.error(error.message); // "输入验证失败" console.error('原始错误:', error.cause); });
finally()
promise.finally():(onFinally)
,ES2018,用于指定一个无论 Promise 最终状态如何(fulfilled 或 rejected)都会执行的回调函数。
onFinally:
()=>any
,回调不接受参数,当 Promise 敲定(settled)时调用的函数(无论成功或失败)。返回:
promise:
Promise
,返回一个新的 Promise 对象。
基本示例:
基本使用:
jsPromise.resolve('成功') .then(value => console.log('结果:', value)) .catch(err => console.log('错误:', err)) .finally(() => console.log('清理操作'))
核心特性:
总是执行:无论 Promise 是成功还是失败,
onFinally
都会执行js// 成功场景 Promise.resolve('成功') .finally(() => console.log('清理操作')) .then(value => console.log('结果:', value)); // 失败场景 Promise.reject('失败') .finally(() => console.log('清理操作')) .catch(reason => console.log('原因:', reason));
无参数回调:
onFinally
回调不接受任何参数,因为它不知道 Promise 的最终状态jspromise .then(value => { /* ... */ }) .catch(error => { /* ... */ }) .finally(() => { // 这里不知道是成功还是失败 console.log('操作完成'); });
状态保持:
finally()
返回的 Promise 会"镜像"原始 Promise 的状态和值:js// 保持解决状态 Promise.resolve(42) .finally(() => {}) .then(value => console.log(value)); // 42 // 保持拒绝状态 Promise.reject('错误') .finally(() => {}) .catch(reason => console.log(reason)); // "错误"
值保持:
jsPromise.resolve('重要值') .finally(() => {}) .then(value => console.log(value)); // "重要值"(值保留)
错误优先:
finally()
中的错误会覆盖原始值jsPromise.reject('原始错误') .finally(() => { throw new Error('新错误'); }) .catch(error => console.log(error.message)); // "新错误"(原始错误被覆盖)
返回值被忽略:
jsPromise.resolve('原始值') .finally(() => '新值') // 被忽略 .then(value => console.log(value)); // "原始值"
静态方法
resolve()@
Promise.resolve():(value)
,ES2015,用于快速创建一个已解决(fulfilled)的 Promise 对象。提供了一种将值转换为 Promise 的标准方式。
value:
any
,可以是任何类型的值,它决定了返回的 Promise 状态。返回:
promise:
Promise
,返回一个 Promise 对象。
基本示例:
基本使用:
jsconst p1 = Promise.resolve(42); // 等价于 new Promise(resolve => resolve(42)) p1.then(value => console.log(value)); // 输出: 42
核心特性:
参数类型处理规则:
Promise.resolve()
根据传入值的类型有不同处理方式:非 Promise 的普通值:
当前 Promise 状态变成 fulfilled。
thenable 对象:
处理具有
.then()
方法的对象(符合 Promise A+ 规范的 thenable):Promise 对象:
直接返回传入的 Promise(无额外封装):
无参数:
创建 undefined 的已解决 Promise:
执行特性:
同步执行:
Promise.resolve()
同步返回 Promise,但处理 then 时是异步解决js// 同步验证 console.log('开始'); Promise.resolve().then(() => console.log('微任务')); console.log('结束'); // 输出顺序: // 开始 → 结束 → 微任务
错误处理:当 thenable 抛出错误时,返回的 Promise 变为 rejected
jsconst errorThenable = { then: () => { throw new Error('thenable 错误') } }; Promise.resolve(errorThenable) .catch(err => console.log(err.message)); // 输出: "thenable 错误"
reject()@
Promise.reject():(reason)
,ES2015,用于立即创建一个已拒绝(rejected)状态的 Promise 对象。它提供了一种快速失败机制,在异步流程中直接抛出错误或拒绝信号。
reason:
any|Error
,拒绝原因,可以是任意类型(通常为 Error 对象或错误描述)返回:
promise:
Promise
,始终返回一个已拒绝状态(rejected)的 Promise 对象
基本示例:
基本使用:
jsPromise.reject('错误') .catch(err => console.log('捕获:', err));
核心特性:
等效写法:
jsPromise.reject('错误'); // 等效写法 new Promise((_, reject) => reject('错误'));
不可取消性:一旦创建无法取消拒绝状态
jsconst p = Promise.reject('最终错误'); // 无法撤回,必须处理 p.catch(() => {}); // 静默处理避免警告
参数类型:
reason
可以是任意 JS 值:js// 1. 错误对象(最佳实践) Promise.reject(new Error('文件未找到')); // 2. 字符串描述 Promise.reject('无效输入'); // 3. 数字代码 Promise.reject(404); // 4. 复杂对象 Promise.reject({ status: 'error', code: 500 }); // 5. 无参数(默认为 undefined) Promise.reject(); // 相当于 reject(undefined)
执行机制:
同步创建:
Promise.reject()
同步返回 rejected Promisejsconsole.log('开始'); const p = Promise.reject('错误'); console.log('结束'); // 输出顺序:开始 → 结束(同步执行)
异步处理:拒绝原因通过微任务队列传递
jsPromise.reject('错误') .catch(err => console.log('捕获:', err)); console.log('先执行我'); // 输出顺序: // 先执行我 → 捕获:错误
注意事项:
必须处理拒绝:未处理的拒绝会导致"未捕获的Promise拒绝"警告
js// 浏览器控制台会显示警告 Promise.reject('未处理错误'); // 报错:Uncaught (in promise) 未处理错误s
对比
throw
:js// 在 async 函数中 async function fail() { throw '错误'; // 等同于返回 Promise.reject('错误') }
错误对象最佳实践:始终使用 Error 对象保留堆栈跟踪
js// 推荐 Promise.reject(new Error('发生错误')); // 避免 Promise.reject('发生错误'); // 无堆栈信息
进阶示例:
统一错误格式:
jsfunction toErrorPromise(error) { // 包装为统一错误格式 return Promise.reject({ timestamp: Date.now(), error: error.message || String(error) }); } fetchData() .catch(toErrorPromise) .catch(errObj => console.error(errObj));
all()
Promise.all():(iterable)
,ES2015,用于并行处理多个 Promise,当所有 Promise 都成功时返回成功结果,当任意一个 Promise 失败时立即返回失败。
iterable:
Iterator
,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。返回:
promise:
Promise
,返回一个新的 Promise 对象。
基本示例:
基本使用:
js// 成功情况 Promise.all([ Promise.resolve(1), Promise.resolve(2), Promise.resolve(3) ]).then(console.log); // [1, 2, 3] // 失败情况 Promise.all([ Promise.resolve('成功'), Promise.reject('失败1'), Promise.reject('失败2') // 被忽略 ]).catch(console.log); // "失败1"
核心特性:
接受任何可迭代对象:Array、Set、Map等
js// 数组(最常用) Promise.all([promise1, promise2, promise3]); // Set Promise.all(new Set([p1, p2])); // Map(处理键值对) Promise.all( new Map([['key1', p1], ['key2', p2]]) );
元素处理规则:
- Promise 对象:等待其解决/拒绝
- 非 Promise 值:自动用
Promise.resolve()
转换 - 混合类型:允许混合使用 Promise 和非 Promise 值
jsPromise.all([ fetch('/api/users'), // Promise 42, // 数字 → Promise.resolve(42) { name: '测试' } // 对象 → Promise.resolve({...}) ]);
返回值行为:
成功情况:所有 Promise fulfilled
状态:
fulfilled
结果值:数组(结果数组顺序始终与输入顺序一致)
jsPromise.all([ Promise.resolve(1), Promise.resolve(2), Promise.resolve(3) ]).then(console.log); // [1, 2, 3]
失败情况:任意 Promise rejected
状态:
rejected
拒绝原因:第一个拒绝的 Promise 的原因
jsPromise.all([ Promise.resolve('成功'), Promise.reject('失败1'), Promise.reject('失败2') // 被忽略 ]).catch(console.log); // "失败1"
执行机制:
并行执行:所有 Promise 同时启动,执行顺序不固定;但结果保持声明时的顺序:
jsconst delay = (ms, val) => new Promise(resolve => setTimeout(() => { console.log(`完成: ${val}`); resolve(val); }, ms) ); Promise.all([ delay(300, '第三'), delay(100, '第一'), delay(200, '第二') ]).then(arr => console.log('结果:', arr)); /* 输出顺序: 完成: 第一 完成: 第二 完成: 第三 结果: ['第三', '第一', '第二'] ← 保持声明顺序! */
快速失败机制:遇到第一个拒绝立即终止:
jsconst p1 = new Promise(resolve => setTimeout(resolve, 500, '慢速成功')); const p2 = new Promise((_, reject) => setTimeout(reject, 100, '快速失败')); Promise.all([p1, p2]) .catch(err => console.log('捕获:', err)); // 100ms后输出"捕获: 快速失败" // p1 仍在后台运行(但结果被忽略)
错误传播:只有第一个错误被捕获:
jsPromise.all([ Promise.reject('错误1'), Promise.reject('错误2') // 被忽略 ]).catch(err => console.log(err)); // 只输出"错误1"
allSettled()
Promise.allsettled():(iterable)
,ES2020,用于等待所有 Promise 完成(无论成功或失败),并返回每个 Promise 的最终状态和结果。不会因某个 Promise 失败而提前终止。
iterable:
Iterator
,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。返回:
promise:
Promise
,始终返回一个已兑现状态(fulfilled)的 Promise 对象。
基本示例:
基本使用:
jsconst p1 = new Promise(resolve => setTimeout(resolve, 100, '成功')); const p2 = new Promise((_, reject) => setTimeout(reject, 200, '失败')); console.time('耗时'); Promise.allSettled([p1, p2]) .then(() => console.timeEnd('耗时')); // 耗时: ~200ms(等待最慢的完成) /* 输出: [ { status: 'fulfilled', value: '成功' }, { status: 'rejected', reason: '失败' } ] */
核心特性:
参数处理:
- 接受任何可迭代对象(数组、Set 等)
- 元素处理规则:
- Promise 对象:等待其解决
- 非 Promise 值:自动转换为
Promise.resolve(value)
- 混合类型:允许混合使用
js// 混合类型示例 Promise.allSettled([ fetch('/api/data'), // Promise 42, // 非 Promise → 自动转换 Promise.reject('失败') // 拒绝的 Promise ]);
返回值详解:
返回的 Promise 总是 fulfilled 状态,不会 rejected。结果是一个对象数组,每个对象描述原始 Promise 的结果:
jsPromise.allSettled([ Promise.resolve('成功'), Promise.reject('失败'), 42 ]).then(results => console.log(results)); /* 输出: [ { status: 'fulfilled', value: '成功' }, { status: 'rejected', reason: '失败' }, { status: 'fulfilled', value: 42 } ] */
执行机制:
并行执行 + 等待所有完成
jsconst p1 = new Promise(resolve => setTimeout(resolve, 100, '成功')); const p2 = new Promise((_, reject) => setTimeout(reject, 200, '失败')); console.time('耗时'); Promise.allSettled([p1, p2]) .then(() => console.timeEnd('耗时')); // 耗时: ~200ms(等待最慢的完成)
不中断执行:即使有 Promise 被拒绝,其他 Promise 仍继续执行:
jsconst tasks = [ delay(100, '任务1'), Promise.reject('任务2失败'), delay(300, '任务3') ]; Promise.allSettled(tasks).then(results => { console.log('任务2状态:', results[1].status); // 'rejected' console.log('任务3状态:', results[2].status); // 'fulfilled'(仍执行完成) });
结果顺序:输出数组顺序严格匹配输入顺序
jsPromise.allSettled([ delay(300, 'C'), delay(100, 'A'), Promise.reject('B') ]).then(results => { console.log(results[0].value); // 'C' console.log(results[1].value); // 'A' console.log(results[2].reason); // 'B' });
错误处理:返回的 Promise 本身不会 rejected
js// 无需 .catch(),但需处理内部失败 Promise.allSettled([Promise.reject('错误')]) .then(results => { // 仍会执行,results[0].status === 'rejected' });
进阶示例:
批量操作 + 独立处理结果:
js// 批量发送通知,忽略失败项 function sendNotifications(users) { return Promise.allSettled( users.map(user => sendEmail(user.email)) ).then(results => { const successes = results .filter(r => r.status === 'fulfilled') .map(r => r.value); const failures = results .filter(r => r.status === 'rejected') .map(r => r.reason); return { successes, failures }; // 返回值会被 Promise.resolve() 包裹 }); } // 使用 sendNotifications(userList) .then(({successes, failures}) => { console.log(`成功: ${successes.length}, 失败: ${failures.length}`); });
race()
Promise.race():(iterable)
,ES2015,用于获取第一个完成的 Promise 结果(无论成功或失败)。
iterable:
Iterator
,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。返回:
promise:
Promise
,返回一个新的 Promise 对象。
基本示例:
基本使用:
jsconsole.time('总耗时'); Promise.race([ delay(300, '慢速'), delay(100, '中速'), delay(50, '快速') ]).then(result => { console.log('获胜者:', result); // "快速" console.timeEnd('总耗时'); // ~50ms });
核心特性:
参数处理:
- 接受任何可迭代对象(数组、Set 等)
- 元素处理规则:
- Promise 对象:等待其解决
- 非 Promise 值:自动转换为
Promise.resolve(value)
- 混合类型:允许混合使用
jsPromise.race([ fetch('/api/data'), // Promise 42, // 非 Promise → 自动转换 Promise.reject('失败') // 拒绝的 Promise ]);
返回值行为:
返回的 Promise 状态和结果由第一个完成的 Promise 决定:
第一个完成的 Promise 成功:
状态:
fulfilled
结果值:第一个成功 Promise 的结果
jsconst fastResolve = new Promise(res => setTimeout(res, 100, '快速成功')); const slowResolve = new Promise(res => setTimeout(res, 200, '慢速成功')); Promise.race([fastResolve, slowResolve]) .then(console.log); // 100ms后输出"快速成功"
第一个完成的 Promise 失败:
- 状态:
rejected
- 拒绝原因:第一个失败 Promise 的原因
jsconst fastReject = new Promise((_, rej) => setTimeout(rej, 100, '快速失败')); const slowResolve = new Promise(res => setTimeout(res, 200, '慢速成功')); Promise.race([fastReject, slowResolve]) .catch(console.log); // 100ms后输出"快速失败"
- 状态:
执行机制:
短路机制(Short-circuit):一旦有任一 Promise 完成(无论成功/失败),立即返回结果:
jsconsole.time('总耗时'); Promise.race([ delay(300, '慢速'), delay(100, '中速'), delay(50, '快速') ]).then(result => { console.log('获胜者:', result); // "快速" console.timeEnd('总耗时'); // ~50ms });
忽略后续结果:其他未完成的 Promise 继续执行,但结果被忽略:
jsconst p1 = new Promise(resolve => setTimeout(() => { console.log('p1 完成'); // 仍然会执行 resolve('p1'); }, 200) ); const p2 = Promise.resolve('p2'); Promise.race([p1, p2]) .then(winner => console.log('胜者:', winner)); // "p2" /* 输出: 胜者: p2 p1 完成(200ms后) */
any()
Promise.any():(iterable)
,ES2021,用于获取第一个成功的 Promise 结果。当所有 Promise 都失败时,它会返回一个包含所有错误信息的 AggregateError。
iterable:
Iterator
,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。返回:
promise:
Promise
,返回一个新的 Promise 对象。
基本示例:
基本使用:
js// 成功情况:返回第一个成功的 Promise Promise.any([ Promise.reject('错误A'), Promise.resolve('第一个成功'), Promise.resolve('第二个成功') ]).then(console.log); // "第一个成功" // 失败情况:所有 Promise 都拒绝 Promise.any([ Promise.reject('错误1'), Promise.reject('错误2') ]).catch(error => { console.log(error instanceof AggregateError); // true console.log(error.errors); // ['错误1', '错误2'] });
核心特性:
参数处理:
- 接受任何可迭代对象(数组、Set 等)
- 元素处理规则:
- Promise 对象:等待其解决
- 非 Promise 值:自动转换为
Promise.resolve(value)
- 混合类型:允许混合使用
js// 混合类型示例 Promise.allSettled([ fetch('/api/data'), // Promise 42, // 非 Promise → 自动转换 Promise.reject('失败') // 拒绝的 Promise ]);
返回值行为:
成功情况:至少一个 Promise fulfilled
- 状态:
fulfilled
- 结果值:第一个成功的 Promise 的结果
jsPromise.any([ Promise.reject('错误A'), Promise.resolve('第一个成功'), Promise.resolve('第二个成功') ]).then(console.log); // "第一个成功"
- 状态:
失败情况:所有 Promise rejected
- 状态:
rejected
- 拒绝原因:
AggregateError
对象(包含所有错误信息)
jsPromise.any([ Promise.reject('错误1'), Promise.reject('错误2') ]).catch(error => { console.log(error instanceof AggregateError); // true console.log(error.errors); // ['错误1', '错误2'] });
- 状态:
执行机制:
短路成功(Short-circuit on fulfillment):当第一个 Promise 成功时立即返回
jsconst p1 = new Promise(resolve => setTimeout(resolve, 100, '快速成功')); const p2 = new Promise(resolve => setTimeout(resolve, 200, '慢速成功')); const p3 = Promise.reject('失败'); Promise.any([p3, p1, p2]) .then(result => console.log(result)); // 100ms后输出"快速成功"
等待所有失败(Wait for all rejections):当所有 Promise 都失败时,等待所有完成后返回 AggregateError
jsconst slowReject = new Promise((_, reject) => setTimeout(reject, 200, '慢速失败') ); console.time('失败计时'); Promise.any([ Promise.reject('快速失败'), slowReject ]).catch(error => { console.log(error.errors); // ['快速失败', '慢速失败'] console.timeEnd('失败计时'); // ~200ms });
错误处理:必须处理 AggregateError
jsPromise.any([...]) .then(...) .catch(error => { if (error instanceof AggregateError) { console.error('全部失败:', error.errors); } else { console.error('未知错误:', error); } });
忽略后续成功:一旦有 Promise 成功,其他 Promise 的结果将被忽略
jsconst p = new Promise(resolve => setTimeout(resolve, 1000, '慢速')); Promise.any([ Promise.resolve('快速'), p ]).then(() => { // p 仍在运行(但结果被忽略) });
进阶示例:
****:
js****:
js****:
js
try()
Promise.try():(executor)
,ES2025,用于统一处理 Promise 链中的同步错误和异步错误。
executor:
function
,要执行的函数,可以返回普通值或 Promise返回:
promise:
Promise
,返回一个 Promise 对象:- 如果
executor
返回普通值,Promise 以该值 fulfilled - 如果
executor
返回 Promise,则跟随该 Promise 的状态 - 如果
executor
抛出同步错误,Promise 以该错误 rejected
- 如果
基本示例:
基本使用:
jsfunction fetchData(userId) { // 验证输入(可能同步抛出错误) if (!userId) throw new Error('用户ID不能为空'); return fetch(`/api/users/${userId}`); } // 安全启动 Promise.try(() => fetchData(null)) .then(data => console.log(data)) .catch(error => console.error('错误:', error.message)); // 输出: "错误: 用户ID不能为空"
核心特性:
概念与背景:
问题:Promise 链中的同步错误:
在原生 Promise 中,同步错误无法被
.catch()
捕获:js// 同步错误无法被捕获 function randomFn () { if(Math.random() > 0.5) { throw new Error('同步错误') } else { return Promise.reject(new Error('异步错误')) } } randomFn().catch(error => { console.log('永远不会执行:', error); }); // 未捕获错误:Uncaught Error: 同步错误
解决方案:
Promise.try()
:Promise.try()
提供了一种方式,让同步错误也能被 Promise 的错误处理机制捕获jsPromise.try(() => { throw new Error('同步错误'); }).catch(error => { console.log('成功捕获:', error.message); // "同步错误" });
实现原理:
基本实现:
Promise.try()
的核心实现是一个简单的包装器:jsif (!Promise.try) { Promise.try = function(fn) { return new Promise((resolve) => { resolve(fn()); }); }; }
完整实现(处理同步错误):更健壮的实现包含错误处理:
jsif (!Promise.try) { Promise.try = function(fn) { return new Promise((resolve, reject) => { try { // 处理返回值是 Promise 的情况 const result = fn(); if (result && typeof result.then === 'function') { result.then(resolve, reject); } else { resolve(result); } } catch (error) { reject(error); } }); }; }
使用 async/await 的实现:在支持 async/await 的环境中更简洁的实现:
jsif (!Promise.try) { Promise.try = function(fn) { return (async () => fn())(); }; }
与 async/await 的兼容性:在 async 函数中,同步错误会自动被转换为拒绝的 Promise
js// 在 async 函数中,同步错误会自动被转换为拒绝的 Promise async function example() { throw new Error('自动转换为拒绝'); } example().catch(console.error); // 正常工作
withResolvers()【
Promise.withResolvers():()
,ES2024,
返回:
result:
{ promise, resolve, reject }
,
基本示例:
****:
js
核心特性:
****:
js****:
js****:
js
进阶示例:
****:
js****:
js****:
js