网站首页 > 博客文章 正文
Promise 对象代表一个未来的值,它有三种状态:
- pending 待定,这是 Promise 的初始状态,它可能成功,也可能失败,前途未卜
- fulfilled 已完成,这是一种成功的状态,此时可以获取值
- rejected 已拒绝,这是一种失败的状态,此时可查看导致失败的原因
无论成功还是失败,Promise 一旦尘埃落定,结果便不可逆转。fulfilled 和 rejected 状态统称为 resolved(已解决的)状态。
在 JavaScript 中,Promise 的并发处理(Promise Concurrency)指的是同时启动多个 Promise 异步操作,并以某种方式管理它们的结果。
为此,Promise 提供了四种静态方法,每个方法的处理策略各不相同。
- Promise.all() 只要有一个 Promise 失败,则整体立即失败。仅当所有 Promise 都成功时,整体才算成功(大家好才是真的好)
- Promise.race() 整体的状态取决于第一个 resolved 的 Promise(先入为主)
- Promise.allSettled() 整体返回所有 Promise 的状态,无论成功还是失败(一视同仁)
- Promise.any() 只要有一个 Promise 成功,则整体就算成功(好饭不怕晚)
Promise.all()
Promise.all() 是 ES2015 引入的方法。如果顺利的话,它会等待所有 Promise 进入 fulfilled 状态。
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// [3, 42, 'foo']
但是一旦某个 Promise 失败,则整体立即宣告失败。
const promise1 = Promise.reject(new Error('baz'));
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'foo');
});
Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values);
})
.catch((err) => {
console.log('ERR:', err.message);
});
// ERR: baz
Promise.race()
Promise.race() 同样是在 ES2015 引入的方法。它的结果取决于最先进入 resolved 状态的 Promise。
如果最先 resolved 的 Promise 是 fulfilled 状态,那么最终结果也是 fulfilled 状态。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
});
// two
如果第一个 resolved 的 Promise 是 rejected 状态,则结果也是 rejected 状态。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, new Error('two is error!'));
});
Promise.race([promise1, promise2])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error('ERR:', error.message);
});
// ERR: two is error!
Promise.allSettled()
Promise.allSettled() 是 ES2020 引入的方法。它会忠实记录每个 Promise 的状态,无论成功还是失败,平等对待,童叟无欺。
最终值是一个数组,数组元素的 status 表示对应的 Promise 是成功('fulfilled')还是失败('rejected')。成功 Promise 的 value 属性用于储存值,失败 Promise 的 reason 属性用于解释失败原因。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, new Error('two is error!'));
});
Promise.allSettled([promise1, promise2])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error('ERR:', error.message);
});
// [
// { status: 'fulfilled', value: 'one' },
// {
// status: 'rejected',
// reason: Error('two is error!'),
// },
// ];
Promise.any()
Promise.any() 出现的最晚,它是 ES2021 引入的方法。顺利的话,它会等待第一个 fulfilled 的 Promise。
注意它和 Promise.race() 的差别。如果第一个 resolved 的 Promise 是 rejected 状态,.race() 方法会立即接受它,自己也变为 rejected 状态。而 .any() 方法会再等等,看看后续是否有 fulfilled 状态的 Promise 出现。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, new Error('two is error!'));
});
Promise.any([promise1, promise2])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error('ERR:', error.message);
});
// one
如果很不幸,所有的并发 Promise 都以失败告终,则 Promise.any() 也会宣布失败。此时的 .catch() 子句捕获到的错误类型是 AggregateError,它是多个错误对象的组合体。
const promise1 = new Promise((resolve, reject) => {
setTimeout(reject, 500, new Error('one is error!'));
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, new Error('two is error!'));
});
Promise.any([promise1, promise2])
.then((value) => {
console.log(value);
})
.catch((error) => {
console.error('ERR:', error.message);
});
// ERR: All promises were rejected
如果你想查看每个具体的错误信息,可以访问 AggregateError 的 errors 属性,这是一个错误对象的数组。
// ...
Promise.any([promise1, promise2])
.catch((error) => {
console.error(error.errors);
});
// [Error('one is error!'), Error('two is error!')];
参考链接
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise_concurrency
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
完
- 上一篇: 前端面试-手写promise.all的功能
- 下一篇: promise 的用法及常用短语
猜你喜欢
- 2025-08-05 小词all的用法及其常用短语
- 2025-08-05 从崩溃到安稳:Promise.allSettled如何拯救我的异步请求
- 2025-08-05 Promise的九大方法
- 2025-08-05 promise 的用法及常用短语
- 2025-08-05 前端面试-手写promise.all的功能
- 2024-08-14 Promise.all 多任务场景(等待任务全部完成后再执行后续操作)
- 2024-08-14 24届前端备战春招第9天,promise的all方法就...
- 2024-08-14 36 – 新的 Promise 方法:allSettled & any & race
- 2024-08-14 因为实现不了Promise.all,一场面试凉凉了
- 2024-08-14 Promise.all与async/await的应用(promise 和async)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- flutterrun (59)
- powershellfor (73)
- messagesource (71)
- plsql64位 (73)
- vueproxytable (64)
- npminstallsave (63)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- nacos启动失败 (64)
- ssh-add (70)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- qcombobox样式表 (68)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)