【代碼鑑賞】簡單優雅的JavaScript代碼片斷

首個成功的Promise

從一組Promise裏面獲得第一個「成功的」結果,同時得到了併發執行的速度和容災的能力。api

Promise.race不知足需求,由於若是有一個Promise reject,結果Promise也會當即reject;
Promise.all也不知足需求,由於它會 等待全部Promise,而且要求全部Promise都成功resolve。
function firstSuccess(promises){
  return Promise.all(promises.map(p => {
    // If a request fails, count that as a resolution so it will keep
    // waiting for other possible successes. If a request succeeds,
    // treat it as a rejection so Promise.all immediately bails out.
    return p.then(
      val => Promise.reject(val),
      err => Promise.resolve(err)
    );
  })).then(
    // If '.all' resolved, we've just got an array of errors.
    errors => Promise.reject(errors),
    // If '.all' rejected, we've got the result we wanted.
    val => Promise.resolve(val)
  );
}

把resolve的Promise反轉成reject,把reject的Promise反轉成resolve,而後用Promise.all合併起來。
這樣的話,只要有一個原始Promise成功resolve,就會形成Promise.all馬上被reject,實現提早退出!太巧妙了!數組

這個方法適合的場景:promise

  • 有多條路能夠走,其中任意一條路走通便可,其中有一些路失敗也不要緊
  • 爲了加速獲得結果,併發地走多條路,避免瀑布式嘗試

參考自 https://stackoverflow.com/a/3...併發

異步reduce

有時候業務邏輯要求咱們必須串行地處理多個數據,不能像上面那樣併發地處理多個數據。即,經過瀑布式的異步操做,將一個數組reduce成一個值。這個時候能夠巧妙地使用array.reduce:異步

(async () => {
    const data = [1, 2, 3]
    const result = await data.reduce(async (accumP, current, index) => {
      // 後面的處理要等待前面完成
      const accum = await accumP;
      const next = await apiCall(accum, current);
      return next
    }, 0);
    console.log(result)  // 6

    async function apiCall(a, b) {
        return new Promise((res)=> {
            setTimeout(()=> {res(a+b);}, 300)
        })
    }
})()

與更常見的【array.map + Promise.all方案】對比:async

(async () => {
  const data = [1, 2, 3]
  const result = await Promise.all(
    data.map(async (current, index) => {
      // 處理是併發的
      return apiCall(current)
    })
  )
  console.log(result)

  async function apiCall(a) {
    return new Promise((res) => {
      setTimeout(() => {
        res(a * 2)
      }, 300)
    })
  }
})()
  • 兩個方案相同點:對每一個數組項執行處理,而且其中任一次處理的失敗都會形成總體失敗
  • reduce方案是瀑布式的,map方案是併發的
  • reduce方案,當你處理到第n項的時候,你可使用以前的累積量

參考自 https://stackoverflow.com/a/4...code

相關文章
相關標籤/搜索