爲使用者提供可靠的、可協做的JavaScript Promises的一個開放標準javascript
一個promise表示一個異步操做的最終結果。和一個promise交互的主要方式是經過註冊了回調函數的then
方法,其中回調函數可以獲取promise最終的值或者該promise沒法執行的緣由。java
此規範詳述了提供了then
方法的行爲,全部遵循Promises/A+規範的promise實現都可將本標準做爲參照基礎來實施then
方法。所以此規範必須十分穩定。儘管Promises/A+組織可能偶爾作向後兼容的小小改變來修改這一規範,從而解決新發現的邊界狀況,咱們只在謹慎地考慮、討論和測試後,整合一些大的或是不向後兼容的變化。git
從歷史上看,Promises/A+闡明瞭更早的Promises/A建議的行爲條例,將其擴展爲包含實際上存在的行爲,而且刪減了在特殊狀況下和有問題的部分。github
最後,核心的Promises/A+規範不涉及處理如何建立,執行或是拒絕promise,而是選擇聚焦於提供一個可協做的then
方法。將來的其餘規範可能會涉及到這些方面。算法
1.1. 「promise」是一個具備then
方法的對象或函數,其中then
方法遵循此規範。promise
1.2. "thenable"是一個定義了then
方法的對象或函數。異步
1.3. "value"是一個合法的Javascript值(包括undefined
,一個thenable或是一個promise)。函數
1.4. "exception"是一個使用throw
聲明被丟棄的value。測試
1.5. "reason"是一個指明爲何一個promise被拒絕的value。
this
一個promise必須在下列三種狀態之一:pending(待決),fulfilled(完成)或者rejected(拒絕)。
2.1.1. 當promise狀態爲pending:
2.1.1.1. 可能轉換到fulfilled或者rejected狀態。
2.1.2. 當promise狀態爲fulfilled:
2.1.2.1. 必定不會轉換到任何其餘狀態。
2.1.2.2. 必定有一個不能改變的value。
2.1.3. 當promise狀態爲rejected時:
2.1.3.1. 必定不會轉換到任何其餘狀態。
2.1.3.2. 必定有一個不能改變的reason。
這裏的必定不會改變指的是不變恆等(===),但不意味着深不變性。
then
方法一個promise必須提供一個then
方法來獲取它當前或是最終的value或者reason。
一個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
的value做爲其第一個參數。
2.2.2.2. 它必定不會在promise
fulfilled前被調用。
2.2.2.3. 它的調用次數不會超過一次。
2.2.3. 若是onRejected
是一個函數:
2.2.3.1. 它必定在promise
rejected後才被調用,將promise
的reason做爲其第一個參數。
2.2.3.2. 它必定不會在promise
rejected前被調用。
2.2.3.3. 它的調用次數不會超過一次。
2.2.4. onFulfilled
或者onRejected
當且僅當執行環境堆棧只包含平臺代碼時能夠被調用。[見3.1]
2.2.5. onFulfilled
和onRejected
必須以函數的方式被調用(例如:不包含this
value)。
2.2.6. then
在同一個promise中可能被屢次調用。
2.2.6.1. 若是/當promise
被fulfilled後,全部相應的onFulfilled
調用必須按照對then
原始調用的順序 執行。
2.2.6.2. 若是/當promise
被rejected後,全部相應的onFulfilled
調用必須按照對then
原始調用的順 序執行。
2.2.7. then
必須返回一個promise。[見3.3]
promise2=promise1.then(onFulfilled,onRejected);
2.2.7.1. 若是onFulfilled
或者onRejected
返回一個value x
,執行如下promise解決過程:
[[Resolve]](promise2,x)
2.2.7.2. 若是onFulfilled
或者onRejected
拋出一個 exception e
,promise2
必須以e
爲reason來被rejected。
2.2.7.3. 若是onFulfilled
不是一個函數,同時promise1
被fulfilled,promise2
必須使用和promise1
相同的value被fulfilled。
2.2.7.4. 若是onRejected
不是一個函數,同時promise1
被fulfilled,promise2
必須使用和promise1
相同的value被rejected。
promise解決過程表示爲[[Resolve]](promise,x)
,是以一個promise和一個value爲輸入的抽象操做。若是x
是thenable的,同時x表現的有些像一個promise,那麼解決過程試圖讓promise
接受x
的狀態。不然,解決過程用value x
來fulfill promise。
只要promise的實現暴露了一個遵循Promises/A+的then
方法,這種thenable的特性就會使得promise的實現更具通用性,同時使得遵循了Promises/A+的promise實現能和未遵循但有可用then
方法的promise實現共存。
爲了運行[[Resolve]](promise,x)
,執行如下步驟:
2.3.1. 若是promise
和x
指向同一個對象,那麼以TypeError
做爲reason來reject promise
。
2.3.2 若是x
是一個promise,接受它的狀態[見3.4]:
2.3.2.1. 若是x
處於pending狀態時,在x
處於fulfilled或者rejected狀態以前,promise
必須一直保持 pending狀態。
2.3.2.2. 若是/當x
處於fulfilled狀態時,使用一樣的value來fulfill promise
。
2.3.2.3. 若是/當x
處於rejected狀態時,使用一樣的reason來reject promise
。
2.3.3. 若是x
是一個對象或者函數,
2.3.3.1. 讓then
變爲x.then
[見3.5]
2.3.3.2. 若是取x.then
的值致使了一個exception e
的拋出,將e
做爲reason來reject promise
。
2.3.3.3. 若是then
是一個函數,將x
做爲this
來調用它,第一個參數爲resolvePromise
,第二個參 數爲rejectPromise
,其中:
2.3.3.3.1. 若是/當resolvePromise
被一個value y
調用,運行[[Resolve]](promise,y)
.
2.3.3.3.2. 若是/當rejectPromise被一個reason r
調用,用r
來reject promise
。
2.3.3.3.3. 若是resolvePromise
和rejectPromise
都被調用或者對同一參數進行了屢次調用,則第 一次調用優先,其餘全部調用都被忽略。
2.3.3.3.4. 若是調用then
拋出了一個exception e
,
2.3.3.3.4.1 若是resolvePromise
或者rejectPromise
已經被調用過了,則無視。
2.3.3.3.4.2. 不然,以e
爲reason來reject promise
。
2.3.3.4. 若是then
不是一個函數,用x
來fulfill promise
。
2.3.4. 若是then
不是一個對象或函數,用x
來fulfill promise
。
若是一個promise使用參與了一個循環thenable鏈的thenable變爲resolved,例如[[Resolve]](promise,thenable)
的循環性質最終致使[[Resolve]](promise,thenable)
被再次調用,遵循上述算法將致使無限遞歸。鼓勵但不強制要求實現檢測這樣的遞歸,並以提示信息的TypeError
做爲reason來reject promise
。
3.1. 這裏的平臺代碼指引擎,環境和promise的實現代碼。實際上,這個要求確保了在then
被調用的那一輪事件循環以後的新棧中,onFulfilled
和onRejected
異步執行。可使用例如setTimeout
或setImmediate
的宏任務機制,或者例如MutationObserver
或process.nextTick
的微任務機制來實現。因爲promise實現自己就是平臺代碼,可能自身已經包含了一個在其中調用處理程序的任務調度隊列。
3.2. 在嚴格模式下,它們的this
是undefined
;在非嚴格模式下,它是一個全局對象。
3.3. 在知足全部要求的狀況下實現可能容許promise1===promise2
,每一個實現都應記錄是否容許以及在什麼條件下容許promise2===promise1
。
3.4. 一般,只有在x
符合當前實現時,咱們才認爲它是真正的promise。這一條款容許那些特定實現方式接受已知符合要求的promises狀態。
3.5. 這一步首先存儲了對x.then
的引用,接着測試了這個引用,隨後調用這個引用,避免對於x.then
屬性的屢次訪問。這一預防措施對於確保訪問器屬性的一致性很是重要,由於訪問器屬性值可能在檢索間改變。
3.6. 實如今thenable鏈的深度上不該該設置任意限制,並假定超出這一任意限制後將無限遞歸。只有真正的循環應該致使一個TypeError
;若是遇到了一條無限長的鏈上thenable各不相同,正確的行爲是一直遞歸下去。
翻譯此標準是爲了便於本身後續的實現,同時加深對於Promises/A+標準的理解。按我的閱讀習慣,在翻譯中保留了一些在標準中解釋過的專有術語。我的水平不足,翻譯可能存在一些問題,如有不當之處還望指正,謝謝!