Promise 方法

今天继续认识四种 Promise 可以使用的方法,基础的用法可以先参考昨天的文章

  • Promise.all()
  • Promise.allSettled()
  • Promise.race()
  • Promise.any()

Promise.all()

  • 目的:让多个 promise 同时执行
  • 参数接受一个可迭代的物件,但通常会传入 promise 组成的 array 作为参数
  • 每个 promise 完成时,resolve 的值会存入阵列中
  • 所有 promise 都 resolve 才会回传,但只要有其中一个 promise 被拒绝,则整个 Promise.all 立刻被拒绝
function makeDrinks(drinksName, time) {
  return new Promise((resolve, reject) => {
    if (drinksName.includes("ironman")) {
      reject("ironman冬瓜柠檬卖完了");
    }
    setTimeout(() => {
      resolve(`这是你点的${drinksName}`);
    }, time);
  });
}

// 即使珍珠红茶的制作时间最长,但并不会影响回传结果的顺序
// 结果的顺序会遵循每个 promise 在阵列中的顺序
Promise.all([
    makeDrinks("珍珠红茶", 5000),
    makeDrinks("柠檬爱玉", 1000),
    makeDrinks("多多绿", 0),
    ])
    .then((value) => console.log(value));

//[ '这是你点的珍珠红茶', '这是你点的柠檬爱玉', '这是你点的多多绿' ]


// 其中一个 promise被拒绝 
Promise.all([
  makeDrinks("珍珠红茶", 1000),
  makeDrinks("ironman冬瓜柠檬", 2000),
  makeDrinks("柠檬爱玉", 1000),
  makeDrinks("多多绿", 0),
])
  .then((value) => console.log(value))
  .catch((err) => console.log(err));
  
// ironman冬瓜柠檬卖完了

Promise.all() 的失败优先特点可以运用在当这些非同步事件彼此有相依关系时,只要有一个非同步事件无法成功执行,就立即回传被拒绝的失败讯息。

但如果要处理的非同步事件彼此没有相依关系呢?
这时候就可以思考使用Promise.allSettled()

Promise.allSettled()

MDN 定义: The Promise.allSettled() method returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.

  • 也就是说,不管结果是成功或失败,会确认一组非同步事件是否都执行了,并回传各自的结果
Promise.allSettled([
  makeDrinks("珍珠红茶", 3000),
  makeDrinks("ironman冬瓜柠檬", 1000),
  makeDrinks("柠檬爱玉", 1000),
  makeDrinks("多多绿", 0),
])
  .then(value => console.log(value))
  .catch(err => console.log(err));
  
//[
//  { status: 'fulfilled', value: '这是你点的珍珠红茶' },
//  { status: 'rejected', reason: 'ironman冬瓜柠檬卖完了' },
//  { status: 'fulfilled', value: '这是你点的柠檬爱玉' },
//  { status: 'fulfilled', value: '这是你点的多多绿' }
//]  

Promise.race()

  • 和 Promise.all() 雷同,参数接受一个可迭代的物件
  • 任一个 promise 转变状态,就回传一个同样状态的 promise 物件,并且接收其成功值或失败讯息
  • 其余 promise 的结果或错误会被忽略
Promise.race([
  makeDrinks("珍珠红茶", 3000),
  makeDrinks("柠檬爱玉", 2000),
  makeDrinks("多多绿", 1000),
])
  .then(value => console.log(value))
  .catch(err => console.log(err));
  
// 这是你点的多多绿

Promise.any()

  • 类似Promise.race(),当有一个 promise 完成,就回传完成结果
  • 当所有 promise 都被拒绝,则会回传一个特殊物件 AggregateError,会将所有 promise 的失败讯息存在 errors 属性中
Promise.any([
  makeDrinks("ironman冬瓜柠檬", 2000),
  makeDrinks("ironman冬瓜柠檬", 2000),
])
  .then((value) => console.log(value))
  .catch((err) => console.log(err.constructor.name, err.errors));
  
// AggregateError ["ironman冬瓜柠檬卖完了", "ironman冬瓜柠檬卖完了"]

小结

如果被这些看似雷同的方法搞得晕头转向,可以停下来思考这些方法是为了因应现实世界哪些不同的状况而出现,或许就能区分它们之间微妙的差异~

参考资料:
MDN
JAVASCRIPT.INFO
Promise 对象


<<:  Day18-Kubernetes 那些事-Health Check

>>:  [Day 19] - 『转职工作的Lessons learned』 - GraphQL (Hasura) - Query/Mutation

[Day28] 函式

在 Day21 - 物件的基础概念2 中有提到函式是物件的一个子型别,所以它本身就是一个物件,但函式...

自动化测试,让你上班拥有一杯咖啡的时间 | Day 26- 学习 cypress filter 的用法

此系列文章会同步发文到个人部落格,有兴趣的读者可以前往观看喔。 语法 .filter(select...

Day 26: LeetCode Hard+Medium

Day 26: LeetCode Hard+Medium LeetCode 212. Word Se...

[Day_12]资料储存容器 - 练习题

今天来为大家介绍资料储存容器的练习题, 过程跟解法可能跟大家不太一样还请大家见谅, 那就让我们开始吧...

Day 3 - Android Studio 的设置

Day 3 -Android Studio 的设置 听了前面那些介绍,想必大家已经很迫不期待的想要开...