【Promise】Promises/A+中文翻譯

引言

俗話說好記性不如爛筆頭,因此我決定翻譯一下Promise/A+規範,幫助本身更加深入的理解promise,爲以後手擼promise源碼作準備,同時也但願本篇文章對你們也有所幫助。前端

正文

這是一個實現者爲實施者提供的開源的、可互操做的JavaScript Promise規範git

promise表明一個異步操做的最終結果。與promise的主要互動方式是經過then方法註冊回調函數來接收promise的最終值或者promise未完成的緣由。github

該規範詳細描述了then方法的行爲,它提供了一個可互操做的基礎,全部Promises/A + 符合 promise的實現均可以依賴於這個基礎。所以,該規範被認爲是很是穩定的。儘管Promises/A+的做者可能偶爾會修改規範,對其進行一些向後兼容的小修改,以解決新發現的問題,咱們只有在仔細考慮、討論和測試後,纔會集成大型或者不向後兼容的變動。web

歷史上,Promises/A+澄清了早期的Promises/A proposal的行爲條款,將其拓展到涵蓋事實的行爲,而且省略了未指定或有問題的部分。算法

最後,Promises/A+規範的核心不是處理如何建立、完成或者失敗的promises,而是選擇專一於一個可互操做的then方法。將來在配套規範中的工做可能會涉及這些主題。promise

1.術語

  • 1.1 promise是具備then方法的對象或者函數,其行爲符合規範。app

  • 1.2 thenable是定義在then方法上的對象或者函數。異步

  • 1.3 value 是任何合法的JavaScript值(包括undefinedthenable,或者promise函數

  • 1.4 exception是使用拋出語句拋出的值學習

  • 1.5 reason是一個代表promise爲何失敗的值

2.需求

2.1 Promise狀態

  • 2.1.1 當promise狀態爲pending時:

    • 2.1.1.1 能夠變爲完成狀態或者失敗的狀態
  • 2.1.2 當promise狀態爲fulfilled時:

    • 2.1.2.1 不能變爲任何一種狀態

    • 2.1.2.2 必須有一個value,這個value不能改變

  • 2.1.3 當promiserejected時:

    • 2.1.3.1 不能變爲任何一種狀態

    • 2.1.3.2 必須有一個reason,這個reason不能改變

2.2 then方法

promise必須提供一個then方法,來訪問它當前或最終的valuereason

一個promisethen方法接收兩個參數:

promise.then(onFulfilled, onRejected)
複製代碼
  • 2.2.1 onFulfilledonRejected都是可選的參數

    • 2.2.1.1 若是onFulfilled不是函數,必須被忽略

    • 2.2.1.2 若是onRejected 不是函數,必須被忽略

  • 2.2.2 若是onFulfilled是一個函數

    • 2.2.2.1 它必須在promise完成後被調用,而後把promise的值做爲它的第一個參數

    • 2.2.2.2 它不能在promise完成前被調用。

    • 2.2.2.3 它不能被調用超過一次。

  • 2.2.3 若是onRejected是一個函數

    • 2.2.3.1 它必須在promise失敗後被調用,而後把promise的值做爲它的第一個參數

    • 2.2.3.2 它不能在promise失敗前被調用。

    • 2.2.3.3 它不能被調用超過一次。

  • 2.2.4 在執行上下文堆棧(execution context)僅包含平臺代碼以前,不得調用 onFulfilledonRejected[3.1]

  • 2.2.5 onFulfilledonRejected必須做爲函數調用(即沒有this值)[3.2]

  • 2.2.6 then方法可能在同一次promise中被調用屢次

    • 2.2.6.1 若是/當promise完成時,全部相應的onFulfilled回調必須按照最原始的then順序來執行

    • 2.2.6.2 若是/當promise失敗時,全部相應的onRejected回調必須按照最原始的then順序來執行

  • 2.2.7 then方法必須返回一個promise
    promise2 = promise1.then(onFulfilled, onRejected);

    • 2.2.7.1 若是onFulfilledonRejected返回一個值x,請運行Promise Resolution Procedure [[Resolve]](promise2, x)

    • 2.2.7.2 若是onFulfilledonRejected拋出一個異常epromise2必須拒絕並將e做爲reason

    • 2.2.7.3 若是onFulfilled不是一個函數,且promise1爲完成狀態,promise2必須使用與promise1相同的value完成

    • 2.2.7.4 若是onRejected不是一個函數,且promise1爲失敗狀態,promise2必須使用與promise1相同的reason完成

2.3 Promise解決程序

promise解析過程是一個以輸入promisevalue的抽象操做,咱們記做[[Resolve]](promise, x),若是xthenable,假設x的行爲有點像promise,它會嘗試讓promise採用x的狀態。不然,它將使用x值來完成promise

只要有實現Promises/A+兼容的then方法,對thenable的處理容許使用promise實現可以互操做。它還容許Promises/A+實現使用合理的then方法「同化」不一致的實現。

運行[[Resolve]](promise, x),執行如下的步驟:

  • 2.3.1 若是promisex引用同一個對象,則用TypeError做爲reason拒絕promise

  • 2.3.2 若是x是一個promise,則採用它的狀態[3.4]

    • 2.3.2.1 若是xpending狀態,promise必須保持pending狀態直到x成功或者失敗

    • 2.3.2.2 若是x爲完成狀態,用相同的值完成promise

    • 2.3.2.3 若是x爲失敗狀態,用相同的reason拒絕promise

  • 2.3.3 若是x是一個對象或函數

    • 2.3.3.1 讓thenx.then[3.5]

    • 2.3.3.2 若是檢索屬性x.then的結果拋出一個異常e,用e做爲reason拒絕promise

    • 2.3.3.3 若是then是一個函數,把x做爲this調用它,第一個參數resolvePromise 和第二個參數rejectPromise,其中:

      • 2.3.3.3.1 若是resolvePromisey值調用,運行[[Resolve]](promise, y)

      • 2.3.3.3.2 若是rejectPromise被爲rreason調用,用r來拒絕promise

      • 2.3.3.3.3 若是 resolvePromiserejectPromise都被調用,或者對同一個參數進行屢次調用,則第一次調用優先,任何進一步的調用被忽略

    • 2.3.3.4 若是then不是函數,用x來完成promise

  • 2.3.4 若是x不是對象或者函數,用x來完成promise

若是使用參與循環的可循環鏈的可轉換組件解決了一個promise,這樣,[[Resolve]](promise, thenable)的遞歸性質致使了再次調用[[Resolve]](promise, thenable),遵循上述算法將致使無限遞歸。鼓勵(但不是必須)實現來檢測這種遞歸且用包含信息的TypeError做爲reason拒絕promise。[3.6]

3.筆記

3.1

這裏的「平臺代碼」是指引擎,環境和promise實現代碼。在實踐中,這個需求確保onFulfilledonRejected異步執行,在事件循環以後調用then,而且使用一個新棧。這能夠經過setTimeout或者setImmediate宏任務機制,或者使用MutationObserver或者process.nextTick微任務機制來實現。因爲promise實現被視爲平臺代碼,所以它自己可能包含一個任務調度隊列或「蹦牀」在其中調用處理程序。

3.2

也就是說,在嚴格模式下,thisundefined,在寬鬆模式中,它是一個全局對象(global object)

3.3

在知足全部需求的狀況下,能夠容許實現promise2 === promise1,每一個實現都應該記錄它是否可以產生promise2 === promise1以及在何種條件下產生

3.4

一般,只有x來自於當前實例時,才知道它是一個真正的promise,此條款容許使用特定的實現方法來採用已知符合promise的狀態。

3.5

這個過程首先存儲對x.then的引用,而後測試,而後調用這個引用。避免了對x.then屬性的屢次訪問。這些預防措施對於確保訪問者屬性的一致性很是重要,由於訪問者屬性的值可能在兩次檢索之間發生變化。

3.6

實現不該該對thenable鏈的深度設置任何限制,並假設遞歸超出限制。只有真正的循環纔會致使TypeError,若是遇到無窮多個thenable鏈,那麼永遠遞歸是正確的行爲。

總結

熟悉promise規範有助於咱們深入理解promise原理,爲以後看源碼,手寫源碼鋪路~好久不碰英語了,很長時間以後第一次作翻譯,若是有翻譯很差的地方,還但願指出~咱們共同窗習,共同進步~

最後,分享一下個人公衆號「web前端日記」,若是想更加及時的看見文章,立刻就去關注哇😍

相關文章
相關標籤/搜索