理解和使用Promise.all和Promise.race

最近在项目中遇到一次性处理多个Promise,所以就使用了Promise.all这个方法来处理,借此机会也说下怎么使用。

1.Promise.all

Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。

Promise.all 等待所有都完成(或第一个失败)。

 1 let p1 = new Promise((resolve, reject) => {
 2   resolve('成功了')
 3 })
 4 
 5 let p2 = new Promise((resolve, reject) => {
 6   resolve('success')
 7 })
 8 
 9 let p3 = Promse.reject('失败')
10 
11 Promise.all([p1, p2]).then((result) => {
12   console.log(result)               //['成功了', 'success']
13 }).catch((error) => {
14   console.log(error)
15 })
16 
17 Promise.all([p1,p3,p2]).then((result) => {
18   console.log(result)
19 }).catch((error) => {
20   console.log(error)      // 失败了,打出 '失败'
21 })
View Code

如果参数中包含非 promise 值,这些值将被忽略,但仍然会被放在返回数组中(如果 promise 完成的话):

 1 let p = Promise.all([1,2,3]);
 2 
 3 let p2 = Promise.all([1,2,3, Promise.resolve(444)]);
 4 
 5 let p3 = Promise.all([1,2,3, Promise.reject(555)]);
 6 
 7 // 定时器延迟执行
 8 setTimeout(function(){
 9     console.log(p);
10     console.log(p2);
11     console.log(p3);
12 });
13 
14 // 打印信息
15 // Promise { <state>: "fulfilled", <value>: Array[3] }
16 // Promise { <state>: "fulfilled", <value>: Array[4] }
17 // Promise { <state>: "rejected", <reason>: 555 }
View Code

 Promise.all 在任意一个传入的 promise 失败时返回失败。例如,如果你传入的 promise中,有四个 promise 在一定的时间之后调用成功函数,有一个立即调用失败函数,那么 Promise.all 将立即变为失败。

 1 var p1 = new Promise((resolve, reject) => {
 2   setTimeout(resolve, 1000, 'one');
 3 });
 4 var p2 = new Promise((resolve, reject) => {
 5   setTimeout(resolve, 2000, 'two');
 6 });
 7 var p3 = new Promise((resolve, reject) => {
 8   setTimeout(resolve, 3000, 'three');
 9 });
10 var p4 = new Promise((resolve, reject) => {
11   setTimeout(resolve, 4000, 'four');
12 });
13 var p5 = new Promise((resolve, reject) => {
14   reject('reject');
15 });
16 
17 Promise.all([p1, p2, p3, p4, p5]).then(values => {
18   console.log(values);
19 }, reason => {
20   console.log(reason)
21 });
22 
23 //From console:
24 //"reject"
25 
26 //You can also use .catch
27 Promise.all([p1, p2, p3, p4, p5]).then(values => {
28   console.log(values);
29 }).catch(reason => {
30   console.log(reason)
31 });
32 
33 //From console:
34 //"reject"
View Code
需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

2.Promise.race

顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

 1 var p1 = new Promise(function(resolve, reject) {
 2     setTimeout(resolve, 500, "one");
 3 });
 4 var p2 = new Promise(function(resolve, reject) {
 5     setTimeout(resolve, 100, "two");
 6 });
 7 
 8 Promise.race([p1, p2]).then(function(value) {
 9   console.log(value); // "two"
10   // 两个都完成,但 p2 更快
11 });
12 
13 var p3 = new Promise(function(resolve, reject) {
14     setTimeout(resolve, 100, "three");
15 });
16 var p4 = new Promise(function(resolve, reject) {
17     setTimeout(reject, 500, "four");
18 });
19 
20 Promise.race([p3, p4]).then(function(value) {
21   console.log(value); // "three"
22   // p3 更快,所以它完成了
23 }, function(reason) {
24   // 未被调用
25 });
26 
27 var p5 = new Promise(function(resolve, reject) {
28     setTimeout(resolve, 500, "five");
29 });
30 var p6 = new Promise(function(resolve, reject) {
31     setTimeout(reject, 100, "six");
32 });
33 
34 Promise.race([p5, p6]).then(function(value) {
35   // 未被调用
36 }, function(reason) {
37   console.log(reason); // "six"
38   // p6 更快,所以它失败了
39 });
View Code

使用定时器

 1 var p1 = new Promise(function(resolve, reject) {
 2     setTimeout(resolve, 500, "one");
 3 });
 4 var p2 = new Promise(function(resolve, reject) {
 5     setTimeout(resolve, 100, "two");
 6 });
 7 
 8 Promise.race([p1, p2]).then(function(value) {
 9   console.log(value); // "two"
10   // 两个都完成,但 p2 更快
11 });
12 
13 var p3 = new Promise(function(resolve, reject) {
14     setTimeout(resolve, 100, "three");
15 });
16 var p4 = new Promise(function(resolve, reject) {
17     setTimeout(reject, 500, "four");
18 });
19 
20 Promise.race([p3, p4]).then(function(value) {
21   console.log(value); // "three"
22   // p3 更快,所以它完成了
23 }, function(reason) {
24   // 未被调用
25 });
26 
27 var p5 = new Promise(function(resolve, reject) {
28     setTimeout(resolve, 500, "five");
29 });
30 var p6 = new Promise(function(resolve, reject) {
31     setTimeout(reject, 100, "six");
32 });
33 
34 Promise.race([p5, p6]).then(function(value) {
35   // 未被调用
36 }, function(reason) {
37   console.log(reason); // "six"
38   // p6 更快,所以它失败了
39 });
View Code

 

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/race

posted @ 2021-04-25 19:17  任小飞  阅读(207)  评论(0编辑  收藏  举报