开发者社区> 天行无忌> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Promise.all() 原理解析及使用指南

简介: Promise 对象是ECMAScript 6中新增的对象,主要将 JavaScript 中的异步处理对象和处理规则进行了规范化。前面介绍了《Promise.any() 原理解析及使用指南》,本文来介绍另一个方法 Promise.all(promises) ,能够一次并行处理多个 promise,并且只返回一个 promise 实例, 那个输入的所有 promise 的 resolve 回调的结果是一个数组。
+关注继续查看

Promise 对象是ECMAScript 6中新增的对象,主要将 JavaScript 中的异步处理对象和处理规则进行了规范化。前面介绍了《Promise.any() 原理解析及使用指南》,本文来介绍另一个方法 Promise.all(promises) ,能够一次并行处理多个 promise,并且只返回一个 promise 实例, 那个输入的所有 promiseresolve 回调的结果是一个数组。

下面来看看 Promise.all() 是如何工作的。

1.工作原理

Promise.all() 是一个内置的辅助函数,接受一组 promise(或者一个可迭代的对象),并返回一个promise

const allPromise = Promise.all([promise1, promise2, ...]);

可以使用 then 方法提取第一个 promise 的值:

allPromise.then((values) => {
    values; // [valueOfPromise1, valueOfPromise2, ...]
});

也可以使用 async/await 语法:

const values = await allPromise;
console.log(values); // [valueOfPromise1, valueOfPromise2, ...]

Promise.all() 返回的 promise 被解析或拒绝的方式。

如果 allPromise 都被成功解析,那么 allPromise 将使用一个包含各个 promise 已执行完成后的值的数组作为结果。数组中 promise 的顺序是很重要的——将按照这个顺序得到已实现的值。

image.png

但是如果至少有一个 promiserejected ,那么 allPromise 会以同样的原因立即 rejected (不等待其他 promise 的执行)。

image.png

如果所有的 promiserejected ,等待所有的promise 执行完成,但只会返回最先被rejectedpromisereject 原因。

image.png

2. 使用指南

现在来深入介绍一下 Promise.all(), 在这之前,先来定义 2 个简单的函数。

函数 resolveTimeout(value, delay) 将返回一个在经过 delay 时间后有 resolvepromise

function resolveTimeout(value, delay) {
    return new Promise((resolve) => setTimeout(() => resolve(value), delay));
}

函数 rejectTimeout(reason, delay) 将返回一个在经过 delay 时间后有 rejectpromise

function rejectTimeout(reason, delay) {
    return new Promise((r, reject) => setTimeout(() => reject(reason), delay));
}

接下来使用上面定义的2个辅助函数来试试 Promise.all()

2.1 完成所有 promises

下面定义了一个 promise 数组 allPromise ,所有的 promise 都能够成功的 resolve 值,如下:

function resolveTimeout(value, delay) {
    return new Promise((resolve) => setTimeout(() => resolve(value), delay));
}
const fruits = ["potatoes", "tomatoes"];
const vegetables = ["oranges", "apples"];
const allPromise = [
    resolveTimeout(fruits, 2000),
    resolveTimeout(vegetables, 1000),
];
const promise = Promise.all(allPromise);
// 等待... 2秒后
const list = async () => {
    try {
        const result = await promise;
        console.log(result);
    } catch (error) {
        console.log(error.errors);
    }
};
list(); // [ [ 'potatoes', 'tomatoes' ], [ 'oranges', 'apples' ] ]

从上面执行的结果来看 Promise.all() 返回的 promiseresolve 数组是按照执行前 allPromise 的顺序组成其结果。

promise 数组的顺序直接影响结果的顺序,和 promise 执行完成的先后无关。

2.2 一个 promiserejected

将上面数组 allPromise 的第一个 promise 出现异常被 rejected ,如下代码:

const promise = Promise.all([
    rejectTimeout(new Error("fruits is empty"), 5000),
    resolveTimeout(vegetables, 1000),
]);
// 等待...
const list = async () => {
    try {
        const result = await promise;
        console.log(result);
    } catch (error) {
        console.log(error);
    }
};
list(); // Error: fruits is empty

然而,在经过 5秒 之后,第一个 promise 由于异常被 rejected ,使得 allPromise 也被 rejected ,并返回跟第一个 promise 一样的错误信息:Error: fruits is empty ,即使在 1秒 后就完成的第二个 promise 的值也不被采纳。

接下来将数组 allPromise 的所有 promise 都抛出异常被 rejected ,通过定时器将 rejected 的顺序做个调整,如下:

const promise = Promise.all([
    rejectTimeout(new Error("fruits is empty"), 5000),
    rejectTimeout(new Error("vegetables is empty"), 1000),
]);
// 等待...
const list = async () => {
    try {
        const result = await promise;
        console.log(result);
    } catch (error) {
        console.log(error);
    }
};

经过 5秒 之后完成执行,而结果显示为 Error: vegetables is empty ,不难看出 allPromiserejected 的原因是最先 rejectedpromise

Promise.all() 的这种行为被称为快速失败,如果 promise 数组中至少有一个 promiserejected ,那么返回的 promise 也被拒绝。如果promise 数组中所有的都被 rejected ,那么返回的promise 被拒绝的原因是先rejected的那一个。

总结

Promise.all() 是并行执行异步操作并获取所有 resolve 值的最佳方法,非常适合需要同时获取异步操作结果来进行下一步运算的场合。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
简单说下Promise.all和Promise.race区别和使用场景
简单说下Promise.all和Promise.race区别和使用场景
20 0
简单说下Promise.all和Promise.race区别和使用场景
之前面试中,被面试官问道Promise.all在项目上有没有用到和具体使用场景是什么,由于项目上使用的不多,导致回答的不是很好,回去赶紧把相关知识巩固巩固。今天就简单分享下Promise.all和Promise.race的相关的知识点。
139 0
AlwaysON同步的原理及可用模式
早在SQL Server 2005的时候微软就已经实现了数据库的查询分离技术——发布订阅。但生产库和查询库的同步性能较差,时常出现性能问题,因此在大型生产环境中一直被人所诟病。
1261 0
捕获未处理的Promise错误
译者按: 通过监听unhandledrejection事件,可以捕获未处理的Promise错误。 原文: Tracking unhandled rejected Promises 译者: Fundebug 为了保证可读性,本文采用意译而非直译,并且对源代码进行了大量修改。
1206 0
使用LitJSON.dll处理json格式的数据示例
//下载LitJSON.dll:http://download.csdn.net/detail/pukuimin1226/5851711 using System; using System.
745 0
apt-get 使用指南
命令 下面将要介绍的所有命令都需要sudo!使用时请将“packagename”和“string”替换成您想要安装或者查找的程序。 apt-get update——在修改/etc/apt/sources.list或者/etc/apt/preferences之後运行该命令。此外您需要定期运行这一命令以确保您的软件包列表是最新的。 apt-get install pac
1129 0
+关注
天行无忌
技术改变生活、研发构建未来、细节铸造品质!
255
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载