JavaScript Promise.all 和 Promise.race 方法介紹和簡要實現

Promise.all() 方法接受一個包含 Promise 對象或普通值的數組(或其它可迭代對象)做爲參數,並返回一個 Promise。當全部 Promise 對象都 resolve 後,將全部 resolve 值以數組形式做爲 Promise.all() resolve 的結果。若是其中之一的 Promise 被 reject,當即以第一個 reject 的值做爲 Promise.all() reject 結果。數組

在實際應用中,若是須要從幾個接口獲取數據,而且要在全部數據到達後才執行某些操做,就能夠使用Promise.all()promise

const p1 = new Promise(function (resolve) { setTimeout(resolve, 200, 1) })
const p2 = Promise.resolve(2)
const p3 = 3
Promise.all([p1, p2, p3]).then(function (res) { console.log(res) }) // [1,2,3]

如下是代碼實現,須要一個計數器,來確認全部 promise 對象都已經 resolved,以後返回結果。須要一個數組,按順序記錄返回結果。若是使用相似 for (var i = 0; i < iterable[i]; i++) 的方式遍歷,爲避免閉包只能傳入變量引用的問題,須要嵌套一層自執行函數。這裏使用 for ... in 循環,使函數能夠支持除數組外的其它可迭代對象,如數據結構 Set。數據結構

const all = function (iterable) {
  return new Promise(function (resolve, reject) {
    let count = 0, ans = new Array(count)
    for (const i in iterable) {
      const v = iterable[i]
      if (typeof v === 'object' && typeof v.then === 'function') {
        v.then(function (res) {
          ans[i] = res
          if (--count === 0) resolve(ans)
        }, reject)
        count++
      } else {
        ans[i] = v
      }
    }
  })
}

const p1 = new Promise(function (resolve) { setTimeout(resolve, 200, 1) })
const p2 = Promise.resolve(2)
const p3 = 3
all([p1, p2, p3]).then(function (res) { console.log(res) }) // [1,2,3]

Promise.all()Promise.race() 方法接受一個包含 Promise 對象或普通值的數組(或其它可迭代對象)做爲參數,並返回一個 Promise。一旦其中之一的 Promise 對象 resolve 之後,當即把 resolve 的值做爲 Promise.race() resolve 的結果。若是其中之一的對象 reject,Promise.race也會當即 reject。閉包

在實際應用中,若是能夠從幾個接口獲取相同的數據,哪一個接口數據先到就先用哪一個,就能夠使用Promise.race(),所需時間等於其中最快的那個接口。下面是代碼:函數

const race = function (iterable) {
  return new Promise(function (resolve, reject) {
    for (const i in iterable) {
      const v = iterable[i]
      if (typeof v === 'object' && typeof v.then === 'function') {
        v.then(resolve, reject)
      } else {
        resolve(v)
      }
    }
  })
}

const p1 = new Promise(function (resolve) { setTimeout(resolve, 200, 1) })
const p2 = new Promise(function (resolve) { setTimeout(resolve, 100, 2) })
race([p1, p2]).then(function (res) { console.log(res) }) // 2
相關文章
相關標籤/搜索