1. 程式人生 > >深度解刨 ES6 promise.all 方法

深度解刨 ES6 promise.all 方法

介紹all 方法之前先簡單的來看下promise

定義

        Promise 是非同步程式設計的一種解決方案,比傳統的解決方案——回撥函式和事件——更合理和更強大。它由社群最早提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了Promise物件。

   Promise建構函式接受一個函式作為引數,該函式的兩個引數分別是resolvereject。它們是兩個函式,由 JavaScript 引擎提供,不用自己部署。

        Promise例項生成以後,可以用then

方法分別指定resolved狀態和rejected狀態的回撥函式。

簡單使用

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 非同步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

開發中 通常會遇到多個非同步並行的情況   

情景1:(在同一個函式裡面要同時呼叫兩個不同的介面   兩個介面的返回資料   做為下一步操作的依據)

 情景2:(一些第三方的非同步api   以高德地圖逆地理編碼解析介面為例)

該介面每次只解析一個經緯度值 且是非同步的   但我們需求是 獲取到所有解析結果 一次性提交 這就涉及到多個非同步並行的情況

所以在使用promise的情況下我們的程式碼是這樣的 (typescript 可以忽略)

inspectPoints 就是我們需要解析的經緯度陣列 資料結構是[ {lat:22,lng:114}, {lat:22,lng:114}]   遍歷該陣列  返回promise 物件 解析成功的值作為該promise resolve的值  resp 就是我們所有解析地址的promise的集合   傳給promise.all() 

使用async函式得到 我們解析好的結果  await  後面跟的是一個promise 物件 會等待該promise 執行完成並把返回值賦值給前面的變數 

promise.all 方便了我們的開發  接下來我們來看下如何實現 一個promise.all 

一個簡單的函式實現   自己實現promise 的情況下 可以把all函式 定義在promise 的原型上 

該函式接受一個Iterator物件 作為引數  首先我們驗證該引數型別  如果引數型別不對 我們直接丟擲一個型別錯誤

promise_all 返回的也是一個promise  在其then 方法的引數中獲得 非同步的結果  所以我們獲得到引數的length值 建立一個數組 用

一個變數 來計數非同步的執行   接下來遍歷我們的promise 集合  用promise.resolve 把非同步的執行結果傳給我們的then 函式  等待

所有非同步執行完畢 我們就把儲存了執行結果的陣列 傳給我們all方法的then函式