文章出處

原文地址:https://promisesaplus.com/

本篇為原文翻譯+個人理解,若有謬誤請各位指正,謝謝。

尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/4139172.html  ^_^肥仔John

 

一個可靠的可共同協作的JavaScript Promise開放標準

  promise代表一個異步操作的最終結果。主要通過promise的then方法訂閱其最終結果的處理回調函數,和訂閱因某原因無法成功獲取最終結果的處理回調函數。

  本說明將詳述then方法的行為特點,符合Promise/A+規范的promise實現均以then方法為交互核心。Promises/A+組織會因新發現的問題以向后兼容的方式修改規范,且每次修改均會經過嚴格的考慮、討論和測試,因此Promises/A+規范相對來說還是比較穩定的。

  Promises/A+是在Promises/A的基礎上對原有規范進行修正和增強。

  最后,本說明并不涉及如何創建、fulfill或reject promises,而是著重介紹then方法。將來或許在其他說明中涉及這些內容。

1. 術語                                        

  1.1. "promise"擁有then方法且符合Promises/A+標準的對象。

  1.2. "thenable"擁有thne方法的對象。

  1.3. "value"合法的JavaScript對象(包括undefined,thenable對象,promise對象)。

  1.4. "exception"通過throw語句拋出的值。

  1.5. "reason"合法的JavaScript對象,表示promise狀態轉換為rejected的原因。

2. 需求                                        

  2.1. Promise狀態

    promise狀態為pending,fulfilled和rejected中的其中一種。

    2.1.1. 當promise狀態為pending時:

       2.1.1.1. promise的狀態可以轉換為fulfilled或rejected。

  2.1.2. 當promise狀態為fulfilled時:

       2.1.2.1. 無法轉換為其他狀態。

       2.1.2.2. 必須有一個不可改變的值作為onFulfilled事件處理函數的入參

    2.1.3. 當promsie狀態為rejected時:

   2.1.2.1. 無法轉換為其他狀態。

       2.1.2.2. 必須有一個不可改變的值作為onRejected事件處理函數的入參

    上述不可改變的值是指value或reason變量所存儲的值或地址不變,而不是指地址所指向的堆空間內的對象屬性等不可變。

  2.2. then方法

    promise必須提供then方法用于訂閱狀態轉換事件,從而獲取最終值或失敗原因。

    promise的then方法接受兩個入參

promise.then(onFulfilled, onRejected)

    2.2.1.  onFulfilled 和 onRejected 均為可選入參:

      2.2.1.1. 如果 onFulfilled 不是函數類型,則忽略。

      2.2.1.2 如果 onRejected 不是函數類型,則忽略。

    2.2.2.  如果 onFulfilled 為函數時:

      2.2.2.1. 當且僅當promise狀態為fulfilled時才能被調用(晚綁定依然會被調用),并且promise的不可變值將作為 onFulfilled函數 的入參。

      2.2.2.2. 在promise狀態轉換為fulfilled前禁止被調用。

      2.2.2.3. 只能被調用一次。

    2.2.3.  如果 onRejected 為函數時:

      2.2.3.1. 當且僅當promise狀態為rejected時才能被調用(晚綁定依然會被調用),并且promise的不可變值將作為 onRejected函數 的入參。

      2.2.3.2. 在promise狀態轉換為rejected前禁止被調用。

      2.2.3.3. 只能被調用一次。

    2.2.4.  onFulfilled 和 onRejected 當且僅當執行上下文棧中僅包含平臺代碼[3.1]時才執行

    2.2.5.  onFulfilled 和 onRejected 必須以函數的形式來調用(也就是 this對象 在sloppy模式下為全局對象,strict模式下為undefined)[3.2]

    2.2.6.  同一個promise的then方法可被多次調用

      2.2.6.1. 當promise狀態為fulfilled時,將按調用then方法的順序執行 onFulfilled函數 。

      2.2.6.2. 當promise狀態為rejected時,將按調用then方法的順序執行 onRejected函數 。 

    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將執行 reject(e) 。

      2.2.7.3. 如果 promise1的 onFulfilled 不是函數,那么promise1的不可變值將傳遞到promise2并作為promise2的不可變值。

      2.2.7.4. 如果 promise1的 onRejected不是函數,那么promise1的不可變原因將傳遞到promise2并作為promise2的不可變原因,并作為promise2的 onRejected 的入參。

  2.3. Promise處理過程

     Promise處理步驟是對表示形式為 [[Resolve]](promise, x) 的狀態事件處理函數的返回值的抽象處理。如果x為thenable對象,由于thanble對象的行為特性類似于一個promise實例,因此讓x來設置promise的狀態。若x為其他類型則設置promise的狀態為fulfilled并且不可變值為x。

     [[Resolve]](promise, x) 的處理過程如下:

    2.3.1. 如果promise和x指向同一個對象,則將promise的狀態轉換為rejected并且以TypeError作為不可變原因。

    2.3.2. 如果x是一個promise實例,則以x的狀態作為promise的狀態[3.4]

  2.3.2.1. 如果x的狀態為pending,那么promise的狀態也為pending,直到x的狀態變化而變化。

      2.3.2.2. 如果x的狀態為fulfilled,promise的狀態也為fulfilled,并且以x的不可變值作為promise的不可變值。

      2.3.2.3. 如果x的狀態為rejected,promise的狀態也為rejected,并且以x的不可變原因作為promise的不可變原因。

    2.3.3. 如果x是對象或函數

      2.3.3.1. 將x.then賦值給變量then[3.5]

      2.3.3.2. 如果在獲取屬性x.then時拋出異常,則將promise的狀態轉換為rejected并且以e作為promise的不可變原因。

      2.3.3.3. 如果then為函數類型,則以x作為then函數內部的this指針,以promise的resolvePromise和rejectPromise作為入參調用then函數。

        2.3.3.3.1. 如果以y作為入參調用resolvePromise,那么則執行Promise處理過程 [[Resolve]](promise, y) 。

            2.3.3.3.2. 如果以r作為入參調用rejectPromise,那么則將promise狀態轉換為rejected并且以r作為promise的不可變原因。

     2.3.3.3.3. resolvePromise和rejectPromise僅有一個能被調用,且僅能調用一次,重復調用均視作無效操作。

     2.3.3.3.4. 如果調用then方法拋出異常

      2.3.3.4.1. 如果resolvePromise或rejectPromise已經被調用后才拋出異常,則無視。

      2.3.3.4.2. 其他情況則將promise狀態轉換為rejected并且以異常對象e作為promise的不可變原因。

       2.3.3.4. 如果then不是函數,則將promise狀態轉換為fulfilled并且以x作為promise的不可變值。

    2.3.4.如果x不是對象或函數,則將promise狀態轉換為fulfilled并且以x作為promise的不可變值。

    假如不斷以Promise或thenable作為onFulfilled的返回值,那么就會進入Promise處理過程的死循環中,雖然Promise/A+規范并沒有明確規定具體實現需要通過對死循環進行返回TypeError異常的處理,但實現者可以自行考慮該情況的處理方式。[3.6]

3. 備注                                        

  3.1. 這里的“平臺代碼”是指引擎、執行環境和promise實現代碼。實際上,是要求 onFulfilled 和 onRejected 函數為異步執行。瀏覽器可通過 setTimeout 或 setImmediate ,nodejs可通過 MutationObserver 或 process.nextTick 將函數調度到event loop隊列中達到異步執行的效果。

  3.2. 在strict模式下this指針為undefined,而在sloppy模式下this指針為全局對象。

  3.3. 具體實現可允許promise2===promise1,并且需要將promise2===promise1的條件以文檔形式標注說明。

  3.4. x為真正的promise實例。

  3.5. 由于考慮到ES5的getter特性可能會產生副作用,因此在獲取x.then屬性時,應該形如以下方式,防止多次調用x.then。

var then = x.then;
typeof(then) === 'function' && then.call(x, resolvePromise, rejectPromise)

  3.6.具體實現武斷地限制Promise處理過程的遞歸深度,只有真正的死循環才拋出TypeError異常。如果允許無限循環,也是沒問題的。

 版權所有:Promises/A+組織


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()