實現 JavaScript 異步方法 Promise.all

本次的任務javascript

假如。。。。。html

JavaScript v8 引擎發生了重大故障,Promise.all 方法變成了 undefined ,爲了拯救 JavaScript 世界,須要開發一個模塊來解決此問題。java

使用者須要在代碼入口處引入咱們開發的模塊就可渡過此劫,但要求三個月後官方修改此版本,代碼無修改就能自動切換到官方版本。實現 Promise.allnode

首先要知道 Promise 是什麼

promise 是對異步編程的一種抽象。它是一個代理對象,表明一個必須進行異步處理的函數返回的值或拋出的異常。git

promise 最先是在 commonjs 社區提出來的,當時提出了不少規範。比較接受的是 promise/A 規範。後來人們在這個基礎上。提出了 promise/A+規範,也就是實際上的業內推行的規範。ECMAScript 6.0 也是採用的這種規範。es6

英文版:https://promisesaplus.com/github

中文版:【翻譯】Promises/A+規範npm

上面的規範中主要定義的 then 的實現方式,也就是隻規定了 Promise 的核心, Promise.racePromise.allapi 沒有規定。編程

ECMAScript 6.0 Promise.all 規範api

Node.js 兼容性以下圖 點擊查看在線版

clipboard.png

特色

Promise 不須要編譯器/解釋器的支持

未來可能成爲主流的 async-await,以及曾經火過一把的 generator + co,這些都是須要編譯器或者解釋器級別的支持才能使用。

Promise,是徹底能夠利用語言已有特性,做爲一個庫來實現!即便在很是原始的JS運行環境,你也能夠本身實現一個 Promise,而不須要等待其餘人的幫助。

Promise 是語言無關的

Promise 仍是獨立於語言的,若是你要給另一種編程語言實現 Promise,只要照葫蘆畫瓢就好了。

promise 怎麼用

請看這裏,阮一峯的 ECMAScript 6 入門 Promise

實現 Promise.all

Promise.all 接收一個 promise 對象的數組做爲參數,當這個數組裏的全部 promise 對象所有變爲resolve或 有 reject 狀態出現的時候,它纔會去調用 .then 方法,它們是併發執行的。

Promise.all 簡介

Promise.all(promiseArray) 方法是 Promise 對象上的靜態方法,該方法的做用是將多個 Promise 對象實例包裝,生成並返回一個新的 Promise 實例。

參數:promiseArray,是一個 Promise 實例數組

var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    console.log(results);  // [1, 2, 3]
});

在上面的方法中,promise 數組中全部的 promise 實例都變爲resolve 的時候,該方法纔會返回,並將全部結果傳遞 results 數組中。promise 數組中任何一個 promisereject 的話,則整個 Promise.all 調用會當即終止,並返回一個 reject 的新的 promise 對象。reject 使用示例以下:

var p1 = Promise.resolve(1),
    p2 = Promise.reject(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    //then方法不會被執行
    console.log(results);
}).catch(function (e){
    //catch方法將會被執行,輸出結果爲:2
    console.log(2);
});

總結 promise.all 的特色

一、接收一個 Promise 實例的數組或具備 Iterator 接口的對象,

二、若是元素不是 Promise 對象,則使用 Promise.resolve 轉成 Promise 對象

三、若是所有成功,狀態變爲 resolved,返回值將組成一個數組傳給回調

四、只要有一個失敗,狀態就變爲 rejected,返回值將直接傳遞給回調
all() 的返回值也是新的 Promise 對象

實現 Promise.all 方法

function promiseAll(promises) {
  return new Promise(function(resolve, reject) {
    if (!isArray(promises)) {
      return reject(new TypeError('arguments must be an array'));
    }
    var resolvedCounter = 0;
    var promiseNum = promises.length;
    var resolvedValues = new Array(promiseNum);
    for (var i = 0; i < promiseNum; i++) {
      (function(i) {
        Promise.resolve(promises[i]).then(function(value) {
          resolvedCounter++
          resolvedValues[i] = value
          if (resolvedCounter == promiseNum) {
            return resolve(resolvedValues)
          }
        }, function(reason) {
          return reject(reason)
        })
      })(i)
    }
  })
}

npms 地址 promise-all-simple

參考

本身動手實現ES6 Promise

JavaScript Promise迷你書

Promise對象Promise.all()方法的使用

深刻 Promise(一)——Promise 實現詳解

深刻理解 Promise (上)

擴展閱讀

深刻淺出js(Node.js)異步流程控制

相關文章
相關標籤/搜索