Promise.any的作用,如何自己实现一个Promise.any

[[396443]]

本文转载自微信公众号「三分钟学前端」,作者sisterAn。转载本文请联系三分钟学前端公众号。

引言

本文从五个方面介绍 Promise.any :

  • Promise.any 的作用
  • Promise.any 应用场景
  • Promise.any vs Promise.all
  • Promise.any vs Promise.race
  • 手写 Promise.any 实现

下面正文开始

Promise.any

Promise.any() 是 ES2021 新增的特性,它接收一个 Promise 可迭代对象(例如数组),

  • 只要其中的一个 promise 成功,就返回那个已经成功的 promise
  • 如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和 AggregateError 类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起
 
 
 
  1. const promises = [ 
  2.   Promise.reject('ERROR A'), 
  3.   Promise.reject('ERROR B'), 
  4.   Promise.resolve('result'), 
  5.  
  6. Promise.any(promises).then((value) => { 
  7.   console.log('value: ', value) 
  8. }).catch((err) => { 
  9.   console.log('err: ', err) 
  10. }) 
  11.  
  12. // value:  result 

如果所有传入的 promises 都失败:

 
 
 
  1. const promises = [ 
  2.   Promise.reject('ERROR A'), 
  3.   Promise.reject('ERROR B'), 
  4.   Promise.reject('ERROR C'), 
  5.  
  6. Promise.any(promises).then((value) => { 
  7.   console.log('value:', value) 
  8. }).catch((err) => { 
  9.   console.log('err:', err) 
  10.   console.log(err.message) 
  11.   console.log(err.name) 
  12.   console.log(err.errors) 
  13. }) 
  14.  
  15. // err:AggregateError: All promises were rejected 
  16. // All promises were rejected 
  17. // AggregateError 
  18. // ["ERROR A", "ERROR B", "ERROR C"] 

Promise.any 应用场景

  • 从最快的服务器检索资源

来自世界各地的用户访问网站,如果你有多台服务器,则尽量使用响应速度最快的服务器,在这种情况下,可以使用 Promise.any() 方法从最快的服务器接收响应

 
 
 
  1. function getUser(endpoint) { 
  2.   return fetch(`https://superfire.${endpoint}.com/users`) 
  3.     .then(response => response.json()); 
  4.  
  5. const promises = [getUser("jp"), getUser("uk"), getUser("us"), getUser("au"), getUser("in")] 
  6.  
  7. Promise.any(promises).then(value => { 
  8.   console.log(value) 
  9. }).catch(err => { 
  10.   console.log(err); 
  11. }) 
  • 显示第一张已加载的图片(来自MDN)

在这个例子,我们有一个获取图片并返回 blob 的函数,我们使用 Promise.any() 来获取一些图片并显示第一张有效的图片(即最先 resolved 的那个 promise)

 
 
 
  1. function fetchAndDecode(url) { 
  2.   return fetch(url).then(response => { 
  3.     if(!response.ok) { 
  4.       throw new Error(`HTTP error! status: ${response.status}`); 
  5.     } else { 
  6.       return response.blob(); 
  7.     } 
  8.   }) 
  9.  
  10. let coffee = fetchAndDecode('coffee.jpg'); 
  11. let tea = fetchAndDecode('tea.jpg'); 
  12.  
  13. Promise.any([coffee, tea]).then(value => { 
  14.   let objectURL = URL.createObjectURL(value); 
  15.   let image = document.createElement('img'); 
  16.   image.src = objectURL; 
  17.   document.body.appendChild(image); 
  18. }) 
  19. .catch(e => { 
  20.   console.log(e.message); 
  21. }); 

Promise.any vs Promise.all

Promise.any() 和 Promise.all() 从返回结果来看,它们 彼此相反 :

  • Promise.all() :任意一个 promise 被 reject ,就会立即被 reject ,并且 reject 的是第一个抛出的错误信息,只有所有的 promise 都 resolve 时才会 resolve 所有的结果
  • Promise.any() :任意一个 promise 被 resolve ,就会立即被 resolve ,并且 resolve 的是第一个正确结果,只有所有的 promise 都 reject 时才会 reject 所有的失败信息

另外,它们又有不同的 重点 :

  • Promise.all() 对所有实现都感兴趣。相反的情况(至少一个拒绝)导致拒绝。
  • Promise.any() 对第一个实现感兴趣。相反的情况(所有拒绝)导致拒绝。

Promise.any vs Promise.race

Promise.any() 和 Promise.race() 的 关注点 不一样:

  • Promise.any() :关注于 Promise 是否已经解决
  • Promise.race() :主要关注 Promise 是否已经解决,无论它是被解决还是被拒绝

手写 Promise.any 实现

Promise.any 只要传入的 promise 有一个是 fullfilled 则立即 resolve 出去,否则将所有 reject 结果收集起来并返回 AggregateError

 
 
 
  1. MyPromise.all = function(promises){ 
  2.   return new Promise((resolve,reject)=>{ 
  3.     promises = Array.isArray(promises) ? promises : [] 
  4.     let len = promises.length 
  5.     // 用于收集所有 reject  
  6.     let errs = [] 
  7.     // 如果传入的是一个空数组,那么就直接返回 AggregateError 
  8.     if(len === 0) return reject(new AggregateError('All promises were rejected')) 
  9.     promises.forEach((promise)=>{ 
  10.       promise.then(value=>{ 
  11.         resolve(value) 
  12.       },err=>{ 
  13.         len-- 
  14.         errs.push(err) 
  15.         if(len === 0){ 
  16.           reject(new AggregateError(errs)) 
  17.         } 
  18.       }) 
  19.     }) 
  20.   }) 

 

来自:https://github.com/sisterAn/blog

本文标题:Promise.any的作用,如何自己实现一个Promise.any
网页路径:http://www.mswzjz.cn/qtweb/news35/434485.html

攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能