promise.all

Promises in JavaScript are one of the powerful APIs that help us to do Async operations.

JavaScript中的Promise是帮助我们执行异步操作的强大API之一。

Promise.all takes Async operations to the next new level as it helps you to aggregate a group of promises.

Promise.all将Async操作提升到新的水平,因为它可以帮助您汇总一组Promise。

In other words, I can say that it helps you to do concurrent operations (sometimes for free).

换句话说,我可以说它可以帮助您进行并发操作(有时是免费的)。

先决条件: (Prerequisites:)

You have to know what is a Promise in JavaScript.

您必须知道什么是JavaScript中的Promise

什么是Promise.all? (What is Promise.all?)

Promise.all is actually a promise that takes an array of promises as an input (an iterable). Then it gets resolved when all the promises get resolved or any one of them gets rejected.

Promise.all实际上是一个promise,它将一个promise作为输入(可迭代)。 然后,当所有承诺都得到解决或其中任何一个被拒绝时,它就会得到解决。

For example, assume that you have ten promises (Async operation to perform a network call or a database connection). You have to know when all the promises get resolved or you have to wait till all the promises resolve. So you are passing all ten promises to Promise.all. Then, Promise.all itself as a promise will get resolved once all the ten promises get resolved or any of the ten promises get rejected with an error.

例如,假设您有十个诺言(执行网络调用或数据库连接的异步操作)。 您必须知道所有诺言何时得到解决,或者必须等到所有诺言得到解决。 因此,您正在将所有十个承诺传递给Promise.all。 然后,一旦所有十个诺言都得到解决,或者十个诺言中的任何一个因错误而被拒绝,Promise.all本身作为一个诺言将被解决。

Let’s see it in code:

让我们在代码中看到它:

Promise.all([Promise1, Promise2, Promise3]).then(result) => {console.log(result)}).catch(error => console.log(`Error in promises ${error}`))

As you can see, we are passing an array to Promise.all. And when all three promises get resolved, Promise.all resolves and the output is consoled.

如您所见,我们正在将数组传递给Promise.all。 当所有三个诺言都得到解决时,Promise.all就解决了,并且输出得到了控制。

Let’s see an example:

让我们来看一个例子:

// A simple promise that resolves after a given time
const timeOut = (t) => {return new Promise((resolve, reject) => {setTimeout(() => {resolve(`Completed in ${t}`)}, t)})
}// Resolving a normal promise.
timeOut(1000).then(result => console.log(result)) // Completed in 1000// Promise.all
Promise.all([timeOut(1000), timeOut(2000)]).then(result => console.log(result)) // ["Completed in 1000", "Completed in 2000"]

In the above example, Promise.all resolves after 2000 ms and the output is consoled as an array.

在上面的示例中,Promise.all在2000 ms之后解析,并且将输出作为数组进行控制台。

One interesting thing about Promise.all is that the order of the promises is maintained. The first promise in the array will get resolved to the first element of the output array, the second promise will be a second element in the output array and so on.

关于Promise.all的一件有趣的事情是,承诺的顺序得以保持。 数组中的第一个promise将解析为输出数组的第一个元素,第二个promise将为输出数组中的第二个元素,依此类推。

Let’s see another example:

让我们看另一个例子:

// A simple promise that resolves after a given time
const timeOut = (t) => {return new Promise((resolve, reject) => {setTimeout(() => {resolve(`Completed in ${t}`)}, t)})
}const durations = [1000, 2000, 3000]const promises = []durations.map((duration) => {// In the below line, two things happen.// 1. We are calling the async function (timeout()). So at this point the async function has started and enters the 'pending' state.// 2. We are pushing the pending promise to an array.promises.push(timeOut(duration))
})console.log(promises) // [ Promise { "pending" }, Promise { "pending" }, Promise { "pending" } ]// We are passing an array of pending promises to Promise.all
// Promise.all will wait till all the promises get resolves and then the same gets resolved.
Promise.all(promises)
.then(response => console.log(response)) // ["Completed in 1000", "Completed in 2000", "Completed in 3000"]

From the above example, it’s clear that Promise.all waits till all the promises resolve.

从上面的示例可以看出,Promise.all一直等到所有的诺言都化为乌有。

Let’s see what happens if any one of the promises are rejected.

让我们看看如果任何一个承诺都被拒绝会发生什么。

// A simple promise that resolves after a given time
const timeOut = (t) => {return new Promise((resolve, reject) => {setTimeout(() => {if (t === 2000) {reject(`Rejected in ${t}`)} else {resolve(`Completed in ${t}`)}}, t)})
}const durations = [1000, 2000, 3000]const promises = []durations.map((duration) => {promises.push(timeOut(duration))
})// We are passing an array of pending promises to Promise.all
Promise.all(promises)
.then(response => console.log(response)) // Promise.all cannot be resolved, as one of the promises passed got rejected.
.catch(error => console.log(`Error in executing ${error}`)) // Promise.all throws an error.

As you can see, if one of the promises fails, then all the rest of the promises fail. Then Promise.all gets rejected.

如您所见,如果一个承诺失败,那么所有其他承诺都会失败。 然后Promise.all被拒绝。

For some use cases, you don’t need that. You need to execute all the promises even if some have failed, or maybe you can handle the failed promises later.

对于某些用例,您不需要。 即使某些承诺失败,您也需要执行所有的承诺,否则您可以稍后处理失败的承诺。

Let’s see how to handle that.

让我们看看如何处理。

const durations = [1000, 2000, 3000]promises = durations.map((duration) => {return timeOut(duration).catch(e => e) // Handling the error for each promise.
})Promise.all(promises).then(response => console.log(response)) // ["Completed in 1000", "Rejected in 2000", "Completed in 3000"].catch(error => console.log(`Error in executing ${error}`))
view raw

Promise.all的用例 (Use cases of Promise.all)

Assume that you have to perform a huge number of Async operations like sending bulk marketing emails to thousands of users.

假设您必须执行大量的Async操作,例如向成千上万的用户发送批量营销电子邮件。

Simple pseudo code would be:

简单的伪代码为:

for (let i=0;i<50000; i += 1) {sendMailForUser(user[i]) // Async operation to send a email
}

The above example is straightforward. But it’s not very performant. The stack will become too heavy and at one point of time, JavaScript will have a huge number of open HTTP connection which may kill the server.

上面的例子很简单。 但这不是很出色。 堆栈将变得太沉重,并且在某个时间点,JavaScript将具有大量开放的HTTP连接,这可能会杀死服务器。

A simple performant approach would be to do it in batches. Take first 500 users, trigger the mail and wait till all the HTTP connections are closed. And then take the next batch to process it and so on.

一种简单的执行方法是分批执行。 接收前500个用户,触发邮件,然后等到所有HTTP连接都关闭。 然后处理下一批,以此类推。

Let’s see an example:

让我们来看一个例子:

// Async function to send mail to a list of users.
const sendMailForUsers = async (users) => {const usersLength = users.lengthfor (let i = 0; i < usersLength; i += 100) { const requests = users.slice(i, i + 100).map((user) => { // The batch size is 100. We are processing in a set of 100 users.return triggerMailForUser(user) // Async function to send the mail..catch(e => console.log(`Error in sending email for ${user} - ${e}`)) // Catch the error if something goes wrong. So that it won't block the loop.})// requests will have 100 or less pending promises. // Promise.all will wait till all the promises got resolves and then take the next 100.await Promise.all(requests).catch(e => console.log(`Error in sending email for the batch ${i} - ${e}`)) // Catch the error.}
}sendMailForUsers(userLists)

Let’s consider another scenario: You have to build an API that gets information from multiple third-party APIs and aggregates all the responses from the APIs.

让我们考虑另一种情况:您必须构建一个API,该API可从多个第三方API获取信息并汇总来自这些API的所有响应。

Promise.all is the perfect way of doing that. Let’s see how.

Promise.all是做到这一点的完美方法。 让我们看看如何。

// Function to fetch Github info of a user.
const fetchGithubInfo = async (url) => {console.log(`Fetching ${url}`)const githubInfo = await axios(url) // API call to get user info from Github.return {name: githubInfo.data.name,bio: githubInfo.data.bio,repos: githubInfo.data.public_repos}
}// Iterates all users and returns their Github info.
const fetchUserInfo = async (names) => {const requests = names.map((name) => {const url = `https://api.github.com/users/${name}`return fetchGithubInfo(url) // Async function that fetches the user info..then((a) => {return a // Returns the user info.})})return Promise.all(requests) // Waiting for all the requests to get resolved.
}fetchUserInfo(['sindresorhus', 'yyx990803', 'gaearon']).then(a => console.log(JSON.stringify(a)))/*
Output:
[{"name": "Sindre Sorhus","bio": "Full-Time Open-Sourcerer ·· Maker ·· Into Swift and Node.js ","repos": 996
}, {"name": "Evan You","bio": "Creator of @vuejs, previously @meteor & @google","repos": 151
}, {"name": "Dan Abramov","bio": "Working on @reactjs. Co-author of Redux and Create React App. Building tools for humans.","repos": 232
}]
*/

To conclude, Promise.all is the best way to aggregate a group of promises to a single promise. This is one of the ways of achieving concurrency in JavaScript.

总而言之,Promise.all是将一组诺言聚合为一个诺言的最佳方法。 这是在JavaScript中实现并发的方法之一。

Hope you liked this article. If you did, please clap and share it.

希望您喜欢这篇文章。 如果您这样做了,请鼓掌并分享。

Even if you didn’t, that’s fine you can do it anyway :P

即使您没有,也可以这样做:P

翻译自: https://www.freecodecamp.org/news/promise-all-in-javascript-with-example-6c8c5aea3e32/

promise.all

promise.all_所有您需要了解的Promise.all相关推荐

  1. 什么是Promise?前端开发人员会使用Promise简直就是如虎添翼

    一.什么是Promise 目录 一.什么是Promise 1.Promise到底是做什么的呢? 2.什么是回调地狱. 二.Promise基本语法 三.什么情况下需要使用Promise 四.Promis ...

  2. promise的三种状态_一.Promise中核心逻辑的实现

    首先看一下Promise代码: let promise =new Promise((resolve,reject)=>{resolve('成功');//reject('失败'); }) prom ...

  3. promise用法_图解 Promise 实现原理(四):Promise 静态方法实现

    作者:Morrain 转发链接:https://mp.weixin.qq.com/s/Lp_5BXdpm7G29Z7zT_S-bQ 前言 Promise 是异步编程的一种解决方案,它由社区最早提出和实 ...

  4. Promise的基础使用与生成器配合Promise解决回调地狱

    经过几天对Promise的了解,希望可以帮助到大家. 什么是回调地狱         说起回调地狱 首先想到的是异步 在js中我们经常会大量使用异步回调,常用的ajxa请求 来看下面这段代码: fun ...

  5. Promise在各种场景的使用(Promise.all、Promise.allSettled、Promise.race、Promise.any)

    1.共有三个接口,接口二要根据接口一返回的数据判断是否执行,接口二需要接口一的返回值作为参数:接口三要根据接口二返回的数据判断是否执行,接口三需要接口二的返回值作为参数. const getCatal ...

  6. Promise详解-手写Promise,实现一款自己的简易Promise

    Promise 是ES6异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息: 从本意上讲,它是承诺,承诺它过一段时间会给你一个结果. promise有三种状态: ...

  7. future promise java_第四章 Future和Promise

    Netty是一个异步网络处理框架,在实现中大量使用了Future机制,并在Java自带Future的基础上,增加了Promise机制.这两者的目的都是使异步编程更加方便使用.在阅读源码之前,我们需要对 ...

  8. C++多线程:异步操作std::async和std::promise

    文章目录 std::async 简介 使用案例 std::promise 简介 成员函数 总结 之前的文章中提到了C++多线程中的异步操作机制 C++ 多线程:future 异步访问类(线程之间安全便 ...

  9. ES6中的Promise详解

    Promise 在 JavaScript 中很早就有各种的开源实现,ES6 将其纳入了官方标准,提供了原生 api 支持,使用更加便捷. 定义 Promise 是一个对象,它用来标识 JavaScri ...

最新文章

  1. CQOI2019(十二省联考)游记
  2. 如何使用 AutoPilot 对作业自动调优?
  3. 数据结构与算法之-----总览
  4. 7-7Hadoop学习之常用Linux命令与集群配置
  5. 【Statistics】10g中 Automatic Statistics Collection维护窗口之探查
  6. javascript简单介绍总结(二)
  7. 关于Environment类的使用
  8. python 将毫秒转换成日期_Python将毫秒转换为datetime并返回
  9. JAVA8 日期和时间(LocalDate、LocalDateTime、ZoneId、Duration、Period、Instant)API 用法详解
  10. freemarker ftl模板语法和指令
  11. 专业物联网数据采集解决方案,专业无线传感器,专业非接触测量数据采集,非侵入式数据采集
  12. 阿里P8面试官总结的《2021最新java面试题》,搞定90%以上的技术面
  13. extern C和__declspec(dllexport)以及__declspec(dllimport) 和def的简单解析
  14. 基于Android的旅游景点推荐
  15. 微信小程序 nodejs+vue校园学生社团管理系统
  16. 高精度地图-使用ArcMap标注高精度地图
  17. 数据挖掘学习之路:Python去极值方法(极值滤波)
  18. ssh登录报no matching MAC found. Their offer: hmac-sha2-512异常
  19. KCP协议:从TCP到UDP家族QUIC/KCP/ENET
  20. 树莓派usb摄像头网络监控(定时拍照+网络存储)

热门文章

  1. Kubernetes-基本介绍/核心功能/相关术语(一)
  2. 接口目标 java 1614953528
  3. String类的对象的方法 格式小结 java 1202
  4. 包的实际操作 java
  5. web标准三个要素 此标准的好处
  6. jquery-学生列表增删编辑,纯前端操作
  7. linux释放cache
  8. mysql float精度与范围总结
  9. 实实在在做一位教书匠(来自网络)
  10. 零基础:邪恶带你3步快速掌握iSCSI搭建