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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 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 值的最佳方法,非常适合需要同时获取异步操作结果来进行下一步运算的场合。


相关文章
|
18天前
|
存储 缓存 算法
HashMap深度解析:从原理到实战
HashMap,作为Java集合框架中的一个核心组件,以其高效的键值对存储和检索机制,在软件开发中扮演着举足轻重的角色。作为一名资深的AI工程师,深入理解HashMap的原理、历史、业务场景以及实战应用,对于提升数据处理和算法实现的效率至关重要。本文将通过手绘结构图、流程图,结合Java代码示例,全方位解析HashMap,帮助读者从理论到实践全面掌握这一关键技术。
63 13
|
2月前
|
运维 持续交付 云计算
深入解析云计算中的微服务架构:原理、优势与实践
深入解析云计算中的微服务架构:原理、优势与实践
72 1
|
4天前
|
存储 物联网 大数据
探索阿里云 Flink 物化表:原理、优势与应用场景全解析
阿里云Flink的物化表是流批一体化平台中的关键特性,支持低延迟实时更新、灵活查询性能、无缝流批处理和高容错性。它广泛应用于电商、物联网和金融等领域,助力企业高效处理实时数据,提升业务决策能力。实践案例表明,物化表显著提高了交易欺诈损失率的控制和信贷审批效率,推动企业在数字化转型中取得竞争优势。
35 14
|
12天前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
60 1
|
2月前
|
运维 持续交付 虚拟化
深入解析Docker容器化技术的核心原理
深入解析Docker容器化技术的核心原理
53 1
|
2月前
|
存储 供应链 算法
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
60 0
|
2月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
67 0
|
2月前
|
API 持续交付 网络架构
深入解析微服务架构:原理、优势与实践
深入解析微服务架构:原理、优势与实践
45 0
|
2月前
|
存储 供应链 物联网
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
|
2月前
|
存储 供应链 安全
深度解析区块链技术的核心原理与应用前景
深度解析区块链技术的核心原理与应用前景
55 0

热门文章

最新文章

推荐镜像

更多