Promise-any 的作用,如何自己實現一個 Promise-any

引言

本文從五個方面介紹 Promise.any

下面正文開始👇

Promise.any

Promise.any() 是 ES2021 新增的特性,它接收一個 Promise 可迭代對象(例如數組),

const promises = [
  Promise.reject('ERROR A'),
  Promise.reject('ERROR B'),
  Promise.resolve('result'),
]

Promise.any(promises).then((value) ={
  console.log('value: ', value)
}).catch((err) ={
  console.log('err: ', err)
})

// value:  result

如果所有傳入的 promises 都失敗:

const promises = [
  Promise.reject('ERROR A'),
  Promise.reject('ERROR B'),
  Promise.reject('ERROR C'),
]

Promise.any(promises).then((value) ={
  console.log('value:', value)
}).catch((err) ={
  console.log('err:', err)
  console.log(err.message)
  console.log(err.name)
  console.log(err.errors)
})

// err:AggregateError: All promises were rejected
// All promises were rejected
// AggregateError
// ["ERROR A""ERROR B""ERROR C"]

Promise.any 應用場景

  function getUser(endpoint) {
    return fetch(`https://superfire.${endpoint}.com/users`)
      .then(response => response.json());
  }
  
  const promises = [getUser("jp"), getUser("uk"), getUser("us"), getUser("au"), getUser("in")]
  
  Promise.any(promises).then(value ={
    console.log(value)
  }).catch(err ={
    console.log(err);
  })
  function fetchAndDecode(url) {
    return fetch(url).then(response ={
      if(!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      } else {
        return response.blob();
      }
    })
  }
  
  let coffee = fetchAndDecode('coffee.jpg');
  let tea = fetchAndDecode('tea.jpg');
  
  Promise.any([coffee, tea]).then(value ={
    let objectURL = URL.createObjectURL(value);
    let image = document.createElement('img');
    image.src = objectURL;
    document.body.appendChild(image);
  })
  .catch(e ={
    console.log(e.message);
  });

Promise.any vs Promise.all

Promise.any()Promise.all() 從返回結果來看,它們 彼此相反

另外,它們又有不同的 重點

Promise.any vs Promise.race

Promise.any()Promise.race()關注點 不一樣:

手寫 Promise.any 實現

Promise.any 只要傳入的 promise 有一個是 fullfilled 則立即 resolve 出去,否則將所有 reject 結果收集起來並返回 AggregateError

MyPromise.any = function(promises){
  return new Promise((resolve,reject)=>{
    promises = Array.isArray(promises) ? promises : []
    let len = promises.length
    // 用於收集所有 reject 
    let errs = []
    // 如果傳入的是一個空數組,那麼就直接返回 AggregateError
    if(len === 0) return reject(new AggregateError('All promises were rejected'))
    promises.forEach((promise)=>{
      promise.then(value=>{
        resolve(value)
      },err=>{
        len--
        errs.push(err)
        if(len === 0){
          reject(new AggregateError(errs))
        }
      })
    })
  })
}

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

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/sSq0RHW36-I-KKqkBjBKYw