Promises A+規範原文解讀 + es6實現(附詳細註釋)

無界無我發表於2019-03-03

英文官方文件原文:promisesaplus.com/

前言

寫本文的目的,是為了更好的理解promise,通過解讀翻譯原文,逐行解析原文通過程式碼一行一行實現。希望通過這篇文章,讓我們能對promise有更深入的瞭解。

首先介紹promises是什麼,英文的字面意思是“承諾”的意思,接下來promises翻譯我沒有用承諾翻譯這個單詞,因為我覺得有些英文只是一個詞彙,還是直接用英文原文叫法好。

promise的是解決回撥的問題的,通過then的鏈式呼叫,讓我們能更清晰的理解閱讀程式碼。下面直接看原文解讀:

英: An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.

中: 一個開源標準,可與JS互操作的Promises。由 implementers(語意創作這個promises的人或團體)創作,implementers(實現者)。

英: A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.

中: 一個promise代表了非同步操作的最終結果。與一個promise完成互動的主要方法是then方法,該方法會記錄回撥以接收一個promise的成功返回值或者失敗的原因。

英: This specification details the behavior of the then method, providing an interoperable base which all Promises/A+ conformant promise implementations can be depended on to provide. As such, the specification should be considered very stable. Although the Promises/A+ organization may occasionally revise this specification with minor backward-compatible changes to address newly-discovered corner cases, we will integrate large or backward-incompatible changes only after careful consideration, discussion, and testing.

中: 本規範詳細的描述了then方法的行為,提供了一個可互操作的基礎,所有的Promises / A +符合promise實現都可依賴提供。因此,本規範應該被認為是非常穩定的。雖然Promises / A +組織偶爾會修改這個規範,但向後相容更改次數較少,主要解決新發現的案例,我們只有在仔細考慮,討論以及測試之後才會整合大的改動或者向後相容的更改。

英: Historically, Promises/A+ clarifies the behavioral clauses of the earlier Promises/A proposal, extending it to cover de facto behaviors and omitting parts that are underspecified or problematic.

中: 歷史上,Promises / A +闡明瞭先前Promises / A提案的行為條款,將其擴充套件為涵蓋事實上的行為,並略去了未指定或存在問題的部分。

英: Finally, the core Promises/A+ specification does not deal with how to create, fulfill, or reject promises, choosing instead to focus on providing an interoperable then method. Future work in companion specifications may touch on these subjects.

中: 最後,核心Promises / A+規範不涉及如何建立,履行或拒絕promises,而是選擇專注於提供可互操作的方法。未來的配套規範工作可能涉及這些主題。

英: 1.Terminology

中: 1、術語

英: 1.1 “promise” is an object or function with a then method whose behavior conforms to this specification.

中: 1.1 “promise”是一個物件或函式,它的行為符合這個規範。

英: 1.2 “thenable” is an object or function that defines a then method.

中: 1.2 “thenable”是定義then方法的物件或函式。

英: 1.3 “value” is any legal JavaScript value (including undefined, a thenable, or a promise).

中: 1.3 “value”是任何合法的JavaScript值(包括undefined,thenable或promise)。

英: 1.4 “exception” is a value that is thrown using the throw statement.

中: 1.4 “異常”是使用throw語句丟擲的值。

英: 1.5 “reason” is a value that indicates why a promise was rejected.

中: 1.5 “原因”是一個值(結果)表明promise被拒絕的原因。

英: 2.Requirements

2.1.Promise States
複製程式碼

中: 2、要求

2.1.Promise狀態
複製程式碼

英: A promise must be in one of three states: pending, fulfilled, or rejected.

中: 一個promise必須包含初始態, 成功(完成)態, 或者失敗(拒絕)態這三個狀態中的一種。

英: 2.1.1 When pending, a promise:
2.1.1.1 may transition to either the fulfilled or rejected state.

中: 2.1.1 當狀態是初始態, promise:
2.1.1.1 可能轉換到成功態或失敗態。

英: 2.1.2. When fulfilled, a promise:
2.1.2.1. must not transition to any other state.
2.1.2.2. must have a value, which must not change.

中: 2.1.2 當狀態是成功態,promise:
2.1.2.1 不能更改成別的狀態。
2.1.2.2 必須有個不能更改的值(結果)

英: 2.1.3. When rejected, a promise:
2.1.3.1.must not transition to any other state.
2.1.3.2. must have a reason, which must not change.

中: 2.1.3 當狀態是失敗態,promise:
2.1.3.1. 不能更改成別的狀態。
2.1.3.2. 必須有個不能更改的失敗(錯誤)原因

英: Here, “must not change” means immutable identity (i.e. ===), but does not imply deep immutability.

中: 上面,“不能改變”的意思是不可改變的狀態(即 ===),但並不意味著深不可變。

英: 2.2.The then Method
A promise must provide a then method to access its current or eventual value or reason.
A promise’s then method accepts two arguments:
promise.then(onFulfilled, onRejected)

中: 2.2 then方法
一個promise必須有一個then方法來獲取成功的值(結果)或失敗(錯誤)的原因。
一個promise方法接收兩個引數:
promise.then(onFulfilled, onRejected)

英: 2.2.1. Both onFulfilled and onRejected are optional arguments:
2.2.1.1.If onFulfilled is not a function, it must be ignored.
2.2.1.2.If onRejected is not a function, it must be ignored.

中: 2.2.1. onFulfilled和onRejected都是可選引數:
2.2.1.1 如果onFulfilled不是函式,則必須忽略它。
2.2.1.2 如果onRejected不是函式,則必須忽略它。

英: 2.2.2 If onFulfilled is a function:
2.2.2.1.it must be called after promise is fulfilled, with promise’s value as its first argument.
2.2.2.2.it must not be called before promise is fulfilled.
2.2.2.3.it must not be called more than once.

中: 2.2.2 如果onFulfilled是一個函式:
2.2.2.1 必須在promise執行完成後呼叫,promise的返回值作為第一個引數。
2.2.2.2 在promise執行前不得呼叫。
2.2.2.3 只能呼叫一次。

英: 2.2.3.If onRejected is a function,
2.2.3.1.it must be called after promise is rejected, with promise’s reason as its first argument.
2.2.3.2.it must not be called before promise is rejected.
2.2.3.3.it must not be called more than once.

中: 2.2.3 如果onRejected是一個函式:
2.2.3.1 必須在promise執行完成後呼叫,promise的錯誤原因作為第一個引數。
2.2.3.2 在promise執行前不得呼叫。
2.2.3.3 只能呼叫一次。

英: 2.2.4.onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].

中: 2.2.4 在執行上下文堆疊僅包含平臺程式碼之前,不能呼叫onFulfilled或onRejected。[3.1]。

英: 2.2.5 onFulfilled and onRejected must be called as functions (i.e. with no this value). [3.2]

中: onFulfilled和onRejected必須是函式(即 沒有這個值)。[3.2]

英: 2.2.6.then may be called multiple times on the same promise.
2.2.6.1.If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.
2.2.6.2.If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.

中: 2.2.6 then方法可能會在相同的promise被多次呼叫。
2.2.6.1 如果/當promise成功時,所有各自的onFulfilled回撥必須按照其始發呼叫的順序執行。
2.2.6.2 如果/當promise失敗時,所有各自的onRejected回撥必須按照其始發呼叫的順序執行。

英: 2.2.7. then must return a promise [3.3].
promise2 = promise1.then(onFulfilled, onRejected);
2.2.7.1.If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).
2.2.7.2.If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.
2.2.7.3.If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.
2.2.7.4.If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.

中: 2.2.7 then方法必須返回一個promise。[3.3]
例如:promise2 = promise1.then(onFulfilled, onRejected);
2.2.7.1 如果onFulfilled或onRejected返回一個值(結果)x,執行Promise的解決程式 [[Resolve]](promise2,x)。
2.2.7.2 如果onFulfilled或onRejected引發異常e,promise2必須以e作為拒絕原因。
2.2.7.3 如果onFulfilled不是一個函式並且promise1是被成功,那麼promise2必須用與promise1相同的值執行。
2.2.7.4 如果onRejected不是函式並且promise1是被失敗,那麼promise2必須用與promise1相同的失敗原因。

英: 2.3.The Promise Resolution Procedure

中: 2.3 Promise的解決程式

英: The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.

中: Promise的解決程式是一個抽象操作,取得輸入的promise和一個值(結果),我們表示為 [[Resolve]](promise, x)。
[[Resolve]](promise, x)的意思是建立一個方法Resolve方法執行時傳入兩個引數promise和x(promise成功態時返回的值)。如果x是一個thenable(見上文術語1.2),它試圖創造一個promise採用x的狀態,假設x的行為至少貌似promise。否則,它用x值執行promise。

英: This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.

中: 對thenable的這種處理允許promise實現互動操作,只要它們暴露Promise / A +相容的方法即可。 它還允許Promises / A +實現通過合理的方法“吸收”不合格的實現。

英: To run [[Resolve]](promise, x), perform the following steps:
2.3.1. if promise and x refer to the same object, reject promise with a TypeError as the reason.

中: 去執行 [[Resolve]](promise, x),需執行以下步驟:
2.3.1 如果promise和x引用同一個物件,則以TypeError為原因拒絕promise。

英: 2.3.2. If x is a promise, adopt its state [3.4]:
2.3.2.1.If x is pending, promise must remain pending until x is fulfilled or rejected.
2.3.2.2.If/when x is fulfilled, fulfill promise with the same value.
2.3.2.3.If/when x is rejected, reject promise with the same reason.

中: 2.3.2 如果x是一個promise,採用它的狀態【3.4】:
2.3.2.1 如果x是初始態,promise必須保持初始態(即遞迴執行這個解決程式),直到x被成功或被失敗。(即,直到resolve或者reject執行)
2.3.2.2 如果/當x被成功時,用相同的值(結果)履行promise。
2.3.2.3 如果/當x被失敗時,用相同的錯誤原因履行promise。

英: 2.3.3.Otherwise, if x is an object or function,
2.3.3.1.Let then be x.then. [3.5]
2.3.3.2.If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
2.3.3.3.If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise, where:
2.3.3.3.1.If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
2.3.3.3.2.If/when rejectPromise is called with a reason r, reject promise with r.
2.3.3.3.3.If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
2.3.3.3.4.If calling then throws an exception e,
2.3.3.3.4.1.If resolvePromise or rejectPromise have been called, ignore it.
2.3.3.3.4.2.Otherwise, reject promise with e as the reason.
2.3.3.4.If then is not a function, fulfill promise with x.

中: 2.3.3 否則,如果x是一個物件或函式,
2.3.3.1 讓then等於x.then。【3.5】
2.3.3.2 如果x.then導致丟擲異常e,拒絕promise並用e作為失敗原因。
2.3.3.3 如果then是一個函式,則使用x作為此引數呼叫它,第一個引數resolvePromise,第二個引數rejectPromise,其中:
2.3.3.3.1 如果使用值(結果)y呼叫resolvePromise,執行[[Resolve]](promise,y)我的解決程式的名字是resolveExecutor。
2.3.3.3.2 如果使用拒絕原因r呼叫resolvePromise,執行reject(r)。
2.3.3.3.3 如果resolvePromise和rejectPromise都被呼叫,或者對同一個引數進行多次呼叫,則第一次呼叫優先,並且任何進一步的呼叫都會被忽略。
2.3.3.3.4 如果呼叫then方法丟擲異常e,
2.3.3.3.4.1 如果resolvePromise或rejectPromise已經呼叫了,則忽略它。
2.3.3.3.4.2 否則,以e作為失敗原因拒絕promise。
2.3.3.4 如果then不是一個物件或者函式,則用x作為值(結果)履行promise。

英: 2.3.4.If x is not an object or function, fulfill promise with x.
If a promise is resolved with a thenable that participates in a circular thenable chain, such that the recursive nature of [[Resolve]](promise, thenable) eventually causes [[Resolve]](promise, thenable) to be called again, following the above algorithm will lead to infinite recursion. Implementations are encouraged, but not required, to detect such recursion and reject promise with an informative TypeError as the reason. [3.6]

中: 2.3.4 如果x不是一個物件或函式,則用x作為值履行promise。
如果一個primse是通過一個thenable參與一個迴圈的可連結表示式來解決的thenable鏈,那麼[[Resolve]](promise,thenable)的遞迴性質最終會導致[[Resolve]](promise,thenable)被再次呼叫, 上述演算法將導致無限遞迴。 支援這種實現,但不是必需的,來檢測這種遞迴併以一個資訊性的TypeError為理由拒絕promise。【3.6】

英: 3.Notes

    3.1.Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.
複製程式碼

中: 3.註釋

    3.1 這裡的“平臺程式碼”是指引擎,環境和primise實現程式碼。在實踐中,這個要求確保onFulfilled和onRejected非同步執行,在事件迴圈開始之後then被呼叫,和一個新的堆疊。這可以使用諸如setTimeout或setImmediate之類的“巨集任務”機制,或者使用諸如MutationObserver或process.nextTick的“微任務”機制來實現。由於promise實現被認為是經過深思熟慮的平臺程式碼,因此它本身可能包含呼叫處理程式的任務排程佇列或或稱為“trampoline”(可重用的)的處理程式。
複製程式碼

英: 3.2.That is, in strict mode this will be undefined inside of them; in sloppy mode, it will be the global object.

中: 3.2 即:在嚴格模式下是undefined;非嚴格模式下是全域性物件。

英: 3.3.Implementations may allow promise2 === promise1, provided the implementation meets all requirements. Each implementation should document whether it can produce promise2 === promise1 and under what conditions.

中: 3.3 實現可能會允許promise2 === promise1, 前提是實現符合所有的要求。每個實現應該記錄它是否可以產生promise2 === promise1以及在什麼條件下。

英: 3.4.Generally, it will only be known that x is a true promise if it comes from the current implementation. This clause allows the use of implementation-specific means to adopt the state of known-conformant promises.

中: 3.4 通常,只有當它是來自當前的實現時才會知道x是一個真正的promise。該條款允許使用具體實現方法來採用已知符合性promise的狀態。

英: 3.5.This procedure of first storing a reference to x.then, then testing that reference, and then calling that reference, avoids multiple accesses to the x.then property. Such precautions are important for ensuring consistency in the face of an accessor property, whose value could change between retrievals.

中: 3.5 首先儲存對x.then的引用,然後測試和呼叫該引用,避免多次使用x.then屬性。這樣的注意事項對於確保訪問器的屬的一致性性非常重要,其值(結果)可能在取回時改變。

英: 3.6.Implementations should not set arbitrary limits on the depth of thenable chains, and assume that beyond that arbitrary limit the recursion will be infinite. Only true cycles should lead to a TypeError; if an infinite chain of distinct thenables is encountered, recursing forever is the correct behavior.

中: 3.6 實現不應該對thenable鏈做任意設定限制,假定超出該任意設定限制遞迴將是無限的。只有真正的迴圈才導致TypeError; 如果遇到不同的thenables的無限鏈,一直遞迴是正確的行為。

英: To the extent possible under law, the Promises/A+ organization has waived all copyright and related or neighboring rights to Promises/A+ Promise Specification. This work is published from: United States.

中: 在法律允許的範圍內,Promises / A +組織已放棄所有版權及Promises / A +規範的相關或相鄰權利。本作品發表於:美國。

———以上是原文翻譯

啥也別說上程式碼

class MyPromise {
  constructor(executor) {
    //快取this
    ;let self = this
    //設定初始態
    ;self.status = `pending`
    //定義成功的值預設undefined
    ;self.value = undefined
    //定義失敗的原因預設undefined
    ;self.reason = undefined
    //定義成功的回撥陣列
    ;self.onResolvedCallbacks = []
    //定義失敗的回撥陣列
    ;self.onRejectedCallbacks = []
    //定義成功時執行的函式
    ;let resolve = value => {
      ;if (value instanceof MyPromise) return value.then(resolve, reject)
      //非同步執行成功回撥
      ;setTimeout(() => {
        if (self.status === `pending`) {
          //把狀態改為成功態
          ;self.status = `fulfilled`
          //儲存成功的值
          ;self.value = value
          //遍歷執行每個成功的回撥
          ;self.onResolvedCallbacks.forEach(onFulfilled => onFulfilled(value))
        }
      })
    }
    //定義失敗時執行的函式
    ;let reject = reason => {
      //非同步執行失敗回撥
      setTimeout(() => {
        if (self.status === `pending`) {
          //把狀態改為失敗態
          ;self.status = `rejected`
          //儲存失敗的原因
          ;self.reason = reason
          //遍歷執行每個失敗的回撥
          ;self.onRejectedCallbacks.forEach(onRejected => onRejected(reason))
        }
      })
    }
    //由於呼叫executor這個方法有可能異常,需要將捕獲的異常reject出去
    ;try {
      //執行傳進來的函式把成功和失敗的方法傳進去
      ;executor(resolve, reject)
    } catch (e) {
      ;reject(e)
    }
  }
  /**
   * @param {value} onFulfilled //值的穿透,預設值往後傳
   * @param {reason} onRejected //預設把失敗原因往後拋
   */
  then(onFulfilled = value => value, onRejected = reason => {throw reason}) {
    //快取this,定義promise2
    ;let self = this
    ;let promise2
    //promise主要解決程式,也是promise的難點
    ;let resolveExecutor = (promise2, x, resolve, reject) => {
      // 定義個標識 promise2是否已經resolve 或 reject了
      ;let isThenCalled = false
      // 2.3.1 如果promise和x引用同一個物件,則以TypeError為原因拒絕promise。
      ;if (promise2 === x) return reject(new TypeError(`迴圈引用!!!`))
      // 2.3.2 如果x是一個promise,採用它的狀態【3.4
      ;if (x instanceof MyPromise) {
        /**
         * 2.3.2.1 如果x是初始態,promise必須保持初始態(即遞迴執行這個解決程式),直到x被成功或被失敗。(即,直到resolve或者reject執行)
         */
        if (x.status === `pending`) {
          x.then(function(y) {
            ;resolveExecutor(promise2, y, resolve, reject)
          }, reject)
        } else {
          // 2.3.2.2 如果/當x被成功時,用相同的值(結果)履行promise。
          // 2.3.2.3 如果/當x被失敗時,用相同的錯誤原因履行promise。
          ;x.then(resolve, reject)
        }
      } else if (x !== null && (typeof x === `object` || typeof x === `function`)) {
        // 2.3.3 否則,如果x是一個物件或函式,
        try {
          // 2.3.3.1 讓then等於x.then。【3.5】
          ;let then = x.then
          if (typeof then === `function`) {
            //2.3.3.3.3 如果resolvePromise和rejectPromise都被呼叫,或者對同一個引數進行多次呼叫,則第一次呼叫優先,並且任何進一步的呼叫都會被忽略。
            ;let resolvePromise = y => {
              //如果promise2已經成功或失敗了,就return掉
              ;if (isThenCalled) return
              ;isThenCalled = true
              //2.3.3.3.1 如果使用值(結果)y呼叫resolvePromise,執行[[Resolve]](promise,y)我的解決程式的名字是resolveExecutor,也就是遞迴呼叫。
              ;resolveExecutor(promise2, y, resolve, reject)
            }
            ;let rejectPromise = r => {
              //如果promise2已經成功或失敗了,就return掉
              ;if (isThenCalled) return
              ;isThenCalled = true
              //2.3.3.3.2 如果使用拒絕原因r呼叫resolvePromise,執行reject(r)。
              ;reject(r)
            };
            // 2.3.3.3 如果then是一個函式,則使用x作為此引數呼叫它,第一個引數resolveExecutor,第二個引數rejectPromise,其中
            ;then.call(x, resolvePromise, rejectPromise)
          } else {
            //到此的話x不是一個thenable物件,那直接把它當成值resolve promise2就可以了
            ;resolve(x)
          }
        } catch (e) {
          //2.3.3.3.4 如果呼叫then方法丟擲異常e,
          //2.3.3.3.4.1 如果resolvePromise或rejectPromise已經呼叫了,則忽略它。
          ;if (isThenCalled) return
          ;isThenCalled = true

          //2.3.3.2 如果x.then導致丟擲異常e,拒絕promise並用e作為失敗原因
          //2.3.3.3.4.2 否則,以e作為失敗原因拒絕promise
          ;reject(e)
        }
      } else {
        //2.3.3.4 如果then不是一個物件或者函式,則用x作為值(結果)履行promise。
        ;resolve(x)
      }
    };
    if (self.status === `fulfilled`) {
      //2.2.7
      return (promise2 = new MyPromise((resolve, reject) => {
        //2.2.4 在執行上下文堆疊僅包含平臺程式碼之前,不能呼叫onFulfilled或onRejected。[3.1]。
        //3.1 這裡的“平臺程式碼”是指引擎,環境和primise實現程式碼。在實踐中,這個要求確保onFulfilled和onRejected非同步執行,在事件迴圈開始之後then被呼叫,和一個新的堆疊。這可以使用諸如setTimeout或setImmediate之類的“巨集任務”機制,或者使用諸如MutationObserver或process.nextTick的“微任務”機制來實現。由於promise實現被認為是經過深思熟慮的平臺程式碼,因此它本身可能包含呼叫處理程式的任務排程佇列或或稱為“trampoline”(可重用的)的處理程式。
        //讓onFulfilled非同步執行
        setTimeout(() => {
          try {
            ;let x = onFulfilled(self.value)
            ;resolveExecutor(promise2, x, resolve, reject)
          } catch (e) {
            ;reject(e)
          }
        })
      }))
    }
    if (self.status === `rejected`) {
      return (promise2 = new MyPromise((resolve, reject) => {
        //2.2.4 在執行上下文堆疊僅包含平臺程式碼之前,不能呼叫onFulfilled或onRejected。[3.1]。
        //3.1 這裡的“平臺程式碼”是指引擎,環境和primise實現程式碼。在實踐中,這個要求確保onFulfilled和onRejected非同步執行,在事件迴圈開始之後then被呼叫,和一個新的堆疊。這可以使用諸如setTimeout或setImmediate之類的“巨集任務”機制,或者使用諸如MutationObserver或process.nextTick的“微任務”機制來實現。由於promise實現被認為是經過深思熟慮的平臺程式碼,因此它本身可能包含呼叫處理程式的任務排程佇列或或稱為“trampoline”(可重用的)的處理程式。
        //讓onFulfilled非同步執行
        setTimeout(() => {
          try {
            ;let x = onRejected(self.reason)
            ;resolveExecutor(promise2, x, resolve, reject)
          } catch (e) {
            ;reject(e)
          }
        })
      }))
    }
    if (self.status === `pending`) {
      return (promise2 = new MyPromise((resolve, reject) => {
        self.onResolvedCallbacks.push(() => {
          try {
            ;let x = onFulfilled(self.value)
            ;resolveExecutor(promise2, x, resolve, reject)
          } catch (e) {
            ;reject(e)
          }
        });
        self.onRejectedCallbacks.push(() => {
          try {
            ;let x = onRejected(self.reason)
            ;resolveExecutor(promise2, x, resolve, reject)
          } catch (e) {
            ;reject(e)
          }
        })
      }))
    }
  }
  catch(onRejected) {
    ;this.then(null, onRejected)
  }
  //立即成功的promise
static resolve(value) {
    return new MyPromise(resolve => {
      ;resolve(value)
    })
  }
  //立即失敗的promise
static reject(reason) {
    return new MyPromise((resolve, reject) => {
      ;reject(reason)
    })
  }
  //promise all方法,只要有一個失敗就失敗了。
static all(promises) {
    return new MyPromise((resolve, reject) => {
      ;let len = promises.length
      ;let resolveAry = []
      ;let count = 0
      for (let i = 0; i < len; i++) {
        promises[i].then(value => {
          ;resolveAry[i] = value
          ;if (++count === len) resolve(resolveAry)
        }, reject)
      }
    })
  }
  //promise race方法,看resolve和reject哪個先返回,就取哪個值,成功就取成功的value,失敗就取失敗的reason。
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      for (let i = 0, l = promises.length; i < l; i++) {
        ;promises[i].then(resolve, reject)
      }
    })
  }
}
module.exports = MyPromise;
複製程式碼

~~~ 如有不妥之處,歡迎大家留言指正,如覺得好請關注,點贊,轉發請註明出處,謝謝! ~~~

郵箱:gameness1212@163.com

相關文章