Promise.all()、Promise.allSettled()、Promise.any()、Promise.race()用法与区别

概述

Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值
一个 Promise 必然处于以下几种状态之一:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 意味着操作成功完成。
  • 已拒绝(rejected): 意味着操作失败。

待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个原因(错误)被拒绝(rejected)。当这些情况之一发生时,我们用
promise 的 then 方法排列起来的相关处理程序就会被调用。如果 promise
在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序就会被调用,因此在完成异步操作和绑定处理方法之间不会存在竞争状态。

Promise.all()、Promise.allSettled()、Promise.any()、Promise.race(),都是处理批量异步请求的

Promise.all()

批量处理多个请求,返回的是所有请求结果组成的数组,这前提
是,所有请求成功,若其中一个失败,就抛出第一个rejected异常,不再继续往下执行。

  • 全部请求成功
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log('value-',values);
});
// expected output: value-[3, 42, "foo"]
  • 有一个请求失败;无论promise3定义在前还是后,只要有是rejected状态,就输出reject抛出的错误信息
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, '失败');
});


Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log('value-',values);
}).catch(err=>{
	console.log('err-',err)
});
// expected output:"err-失败"
  • 有多个请求失败,输出第一个请求失败t抛出的错误信息
const promise1 = Promise.resolve(3);
const promise2 = Promise.reject('失败');
const promise3 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
   console.log('value-',values);
}).catch((err)=>{
   console.log('err-',err)
  });
// expected output: err-失败

Promise.allSettled()

批量处理请求,无论结果是成功或失败,都继续向下执行;执行完毕,输出的是包含promise状态的数组对象。reject也不会走catch

  • 所有请求成功时
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'foo'));
const promise3 = Promise.resolve(4)

Promise.allSettled([promise1, promise2,promise3]).then((results) => {
  	console.log('results:',results)
	results.forEach((result) => console.log(result.status))
}).catch(err=>{
	console.log('err:',err)
});

// expected output:
// "results:" Array [Object { status: "fulfilled", value: 3 }, Object { status: "fulfilled", value: "foo" }, Object { status: "fulfilled", value: 4 }]
// "fulfilled"
// "fulfilled"
// "fulfilled"

  • 有请求失败时
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promise3 = Promise.reject(4)

Promise.allSettled([promise1, promise2,promise3]).then((results) => {
  	console.log('results:',results)
	results.forEach((result) => console.log(result.status))
}).catch(err=>{
	console.log('err:',err)
});

// expected output:
// "results:" Array [Object { status: "fulfilled", value: 3 }, Object { status: "rejected", reason: "foo" }, Object { status: "rejected", reason: 4 }]
// "fulfilled"
// "rejected"
// "rejected

Promise.any()

批量处理请求,当请求中有一个状态为fullfilled状态时,就返回fullfill状态的回调函数结果;当结果有多个状态为fullfilled状态的,就返回第一个fullfilled状态的回调函数结果;当所有请求结果状态为rejected时, 返回AggregateError 错误。
注意:Promise.any() 方法依然是实验性的,尚未被所有的浏览器完全支持

  • 存在请求成功结果时
const promise1 = Promise.resolve(3);
const promise2 = Promise.reject(4);;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.any([promise1, promise2, promise3]).then((values) => {
  console.log('values-',values);
}).catch(err=>{
	console.log('err-',err)
});
//这里有两个请求成功promise1、promise3,返回第一个请求成功的
// expected output: "values-" 3
  • 所有请求都失败
const promise1 = Promise.reject(3);
const promise2 = Promise.reject(4);
const promise3 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'foo');
});

Promise.any([promise1, promise2, promise3]).then((values) => {
  console.log('values-',values);
}).catch(err=>{
	console.log('err-',err)
});

// expected output: "err-" AggregateError: All promises were rejected

Promise.race()

批量处理多个请求,哪个结果先执行完,就输出哪个,无论是结果是成功或者失败,(记忆法:race=赛跑的意思,看谁跑得快)

  • promise2,比promise1更快执行完,因此输出成功的结果“two“
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-',value);
  // Both resolve, but promise2 is faster
});
// expected output: "value-two"

  • promise1和promise2同时请求,即使promise1是rejected状态,也输出“one”;(这跟谁先定义的顺序有关),若promise1是后定义的,promise2是先定义的,则输出promise2,“two”
const promise1 = new Promise((resolve, reject) => {
  setTimeout(reject, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log('value-',value);
 
}).catch((err)=>{
	console.log('err-',err)
});

// expected output: "err-one"
const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'two');
});
const promise1 = new Promise((resolve, reject) => {
  setTimeout(reject, 500, 'one');
});



Promise.race([promise1,promise2]).then((value) => {
    console.log('value-',value);
 
}).catch((err)=>{
	console.log('err-',err)
});

// expected output: "value-two"

区别

  • Promise.allSettled()和Promise.all()

当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个promise的结果时,通常使用Promise.allSettled()。
相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。
总结:
Promise.all()和 Promise.allSettled()都是返回结果数组,而all只有请求全部成功才返回,allSettled是无论失败成功都返回
Promise.all()遇到错误就停止
Promise.allSettled()无论如何执行完

  • Promise.any()和Promise.race()

Promise.any():返回第一个成功的回调函数运行结果
Promise.race():返回第一个回调函数运行结果,无论成功还是失败

  • Promise.any()和Promise.all()

Promise.any() 只要其中的一个 promise 成功,就返回那个已经成功的 promise回调函数执行结果。
Promise.all()只要其中的一个 promise失败,就返回那个已经失败promise的 回调函数执行结果
总结:
Promise.any() 好比逻辑运算符中‘或||’,一个成立则成立,所有不成立才不成立
Promise.all()好比逻辑运算符中“与&&‘,只有都成立则成立,有一个不成立就不成立

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值