Promises/A+規範翻譯

Hi,又是我,之前那篇手擼promise寫的太簡單,被同學吐槽了,說完全沒按照規範來,好的,先在這裏翻譯下規範
原文 https://promisesaplus.com/
時間 2018年11月29日

一個promise代表一個異步操作的最終結果,和promise交互的主要方法是通過它的then方法,then方法是用戶註冊的回調函數,接收promise的最終結果或者promise沒有fulfilled的原因

本規範詳細描述了then方法的行爲,提供了一個可互操作的基礎,所有符合Promises/A+的實現都可以依賴它來提供。

核心Promises/A+規範不處理如何創建、fulfill或reject promise,而是聚焦於then方法,將來的規範可能涉及其他方面。

  1. 技術

    • 1.1 promise是一個行爲符合本規範的,具有then方法的對象或者函數
    • 1.2 thenable是一個定義了then方法的對象或者函數
    • 1.3 value是任何合法的js類型,包括undefined,thenable或者promise
    • 1.4 exception是通過throw拋出的值
    • 1.5 reason是promise rejected時的值
  2. 要求

    • 2.1 Promise狀態

      一個pomise必須處於以下三種狀態之一:pending、fulfilled、rejected

      • pending,可以轉換爲fulfilled或rejected

      • fulfilled,不能轉換爲其他狀態,必須有一個不變的value

      • rejected,不能轉換爲其他狀態,必須有一個不變的reason

        不變的(reason或者value)的意思是immutable identity (i.e. ===),但不意味着 deep immutability

    • 2.2 then方法

      一個promise必須提供一個then方法來接收當前或最終的value或reason

      一個promise的then方法接受兩個參數

      promise.then(onFulfilled, onRejected)
      
      • onFulfilled和onRejected都是可選參數,當它們不是函數時,必須被忽略

      • 如果onFulfilled是函數,它必須在promise fulfilled之後調用,value作爲第一個參數,不能多次調用

      • 如果onRejected是函數,它必須在promise rejected之後調用,reason作爲第一個參數,不能多次調用

      • onFulfilled和onRejected只有在執行上下文只包含平臺代碼時才能調用 [3.1]

      • onFulfilled和onRejected必須作爲函數被調用 (i.e. with no this value) [3.2]

      • then在一個promise中可能被調用多次

      • onFulfilled和onRejected必須按照then調用時的順序來執行(注意這裏還在說then,沒在說catch,通篇都沒提catch)

      • then必須返回一個promise [3.3]

        promise2 = promise1.then(onFulfilled, onRejected);
        

        (注意下面幾句都是對照上面這個例子來說的)

        如果onFulfilled或onRejected返回一個value x,執行Promise Resolution Procedure [[Resolve]](promise2, x)

        如果onFulfilled或onRejected拋出一個exception e,promise2必須rejected,並將e作爲reason;

        如果onFulfilled不是一個函數,當promise1 fulfilled,promise2必須用和promise1相同的value來fulfilled(大概是在說value要傳遞給promise2)

        如果onRejected不是一個函數,當promise1 rejected,promise2必須用和promise1相同的reason來rejected

    • 2.3 Promise Resolution Procedure

      Promise Resolution Procedure是一個抽象的操作,可以表示爲[[Resolve]](promise, x),如果x是一個thenable,它嘗試使promise採用x的狀態,否則,它使用value x來fulfill promise。

      運行[[Resolve]](promise, x),要遵循以下內容:

      • 如果promise和x指向同一個對象,用reason TypeError來reject promise

      • 如果x是一個promise,採用它的狀態 [3.4]。如果x是pending,promise也是pending,直到x變成fulfilled或rejected;如果x是fulfilled,promise用相同的value fulfill,如果x是rejected,promise用相同的reason reject

      • 如果x是對象或者函數,將then方法賦爲x.then [3.5]。

        • 如果x.then拋出一個exception e,用reason e來reject promise。

        • 如果then是函數,將x作爲this來調用then,第一個參數是resolvePromise,第二個參數是rejectPromise。如果用一個value y來調用resolvePromise,運行[[Resolve]](promise, y)。如果用一個reason r來調用rejectPromise,用r來reject promise。如果resolvePromise和rejectPromise都被調用,或者resolvePromise(或rejectPromise)被調用多次,第一個調用優先執行,其他的忽略。如果調用then拋出一個exception e,resolvePromise或rejectPromise已經被調用過,忽略這個e,否則用reason e來reject promise。

        • 如果then不是函數,用value x來fullfill promise

      • 如果x不是對象和函數,用value x來fullfill promise

      如果thenable引起循環調用,可以用一個TypeError來reject promise [3.6]

  3. 注意

    • 3.1 這裏的平臺代碼是指引擎、環境和promise實現代碼,這個要求確保onFulfilled和onRejected在then 調用後,event loop完成此次循環以後,異步執行。這可以通過setTimeout或setImmediate實現,或者通過MutationObserver或provess.nextTick來實現。因爲promise被認爲是由平臺來實現的,所以它自己可能就包含一個任務調度隊列
    • 3.2 在嚴格模式下,onFulfilled和onRejected中的this會是undefined,在非嚴格模式下,是全局對象
    • 3.3 實現可能允許promise2 === promise1,這是符合要求的,每種實現都應該標識是否會產生這樣的情況、在什麼條件下會出現這種情況
    • 3.4 通常,只有x是當前promise實現的一個實例時纔可以採用其狀態,這一條允許使用不同promise實現,但要和當前實現兼容
    • 3.5 首先存儲x.then的引用,然後測試、調用該引用的過程避免了對x.then屬性的多次訪問。這種預防措施用於確保x.then的一致性,防止其在使用過程中改變。
    • 3.6 實現不應該設置thenable調用鏈的深度限制,並假定超過限制後調用就是無限循環了。只有真正的循環才應該導致TypeError,如果確實遇到了無限調用的thenable,一直遞歸是正確的行爲
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章