摘要:在將來的其他規(guī)范中可能會涉及這些沒有提及的內容。它禁止被觸發(fā)多次。如果到了狀態(tài),那么所有的回調函數(shù)都必須按照他們原有的順序進行調用執(zhí)行。
概述
自從準備晉級之后,就拖更了很久了,既然晉級弄完了,那么也恢復更新了。
在面試別人的過程中,發(fā)現(xiàn)基本上沒有人對整個Promise完全了解,因此希望通過這篇文章來幫助大家了解下Promise的全貌。本文的主要內容是Promise/A+規(guī)范的譯文,主要是能夠幫助大家了解下Promise的規(guī)范,以及解決在日常運用中遇到的一些問題。
原文地址為:https://promisesaplus.com/#po...
如果需要測試一個Promise庫是否符合Promise/A+規(guī)范,可以使用這個:https://github.com/promises-a... 。
原文概覽一個標準聲明、可操作的JavaScript Promise——出自開發(fā)者,為了開發(fā)者。
一個promise代表一個異步操作的最終結果。與promise交互的主要方法是通過它的then函數(shù)。這個函數(shù)注冊一個回調函數(shù)來接收promise最終的值(value)或者是沒有成功的原因(reason)。
這篇文檔詳細說明了then方法的具體行為,它為所有的符合Promise/A+規(guī)范的實現(xiàn)提供了一個基礎的交互。像這樣,這個規(guī)范應該設計的非常穩(wěn)定。盡管Promise/A+組織可能偶爾通過一些向后兼容的小修改來調整這個文檔來適應新發(fā)現(xiàn)的場景,我們只會在經(jīng)歷過了小心的思考、討論和測試后增加大的、不向后兼容的修改。
從歷史上來看,Promise/A+闡述了更早的Promise/A的行為規(guī)范,并且在其基礎上進行了擴展,覆蓋了一些實際行為和之前遺漏的問題。
最終,核心的Promise/A+文檔不關心如何去創(chuàng)建、完成(resolve)或者拒絕(reject)一個Promise,而是聚焦在提供一個可交互的then函數(shù)。在將來的其他規(guī)范中可能會涉及這些沒有提及的內容。
1. 術語1.1. "promise"是一個對象或者函數(shù),它擁有一個符合文檔中描述行為的then方法。
1.2. "thenable"是一個有then方法的對象或者函數(shù)。
1.3. "value"是一個合法的JavaScript值(包括undefined, 一個thenable或者一個promise)。
1.4. "exception"是一個使用在throw語句中的拋出來的值。
1.5. "reason"是一個用來表示promise拒絕的原因的值。
2. 要求 2.1 promise狀態(tài)一個promise必須處于一下三種狀態(tài):pending、fulfilled或者rejected。
2.1.1. 當處于pending狀態(tài)時,promise:
2.1.1.1. 可能會轉換成任何其他的狀態(tài)。
2.1.2. 當處于fulfilled狀態(tài)時,promise:
2.1.2.1. 禁止轉換成其他狀態(tài)。
2.1.2.2. 必須有一個無法更改的值。
2.1.3. 當處于rejected狀態(tài)時,promise:
2.1.3.1. 禁止轉換成其他狀態(tài)。
2.1.3.2. 必須有一個無法更改的原因。
在這里,無法更改意味著全等(例如===),但是不代表深比較相等。
2.2 then方法promise必須包含一個then方法來訪問它當前或者最終的值或者原因。
Promise的then方法接收兩個參數(shù):
promise.then(onFulfilled, onRejected)
2.1.1. onFulfilled和onRejected函數(shù)有都有可選的參數(shù):
2.2.1.1. 如果onFulfilled不是一個函數(shù),那么它必須被忽略掉。
2.2.1.2. 如果onRejected不是一個函數(shù),那么它必須被忽略掉。
2.2.2. 如果onFulfilled是一個函數(shù):
2.2.2.1. 它必須在promise到fulfilled狀態(tài)后觸發(fā),promise的值是它的第一個參數(shù)。
2.2.2.2. 它在一個promise到fulfilled狀態(tài)之前禁止被觸發(fā)。
2.2.2.3. 它禁止被觸發(fā)多次。
2.2.3. 如果onRejected是一個函數(shù):
2.2.3.1. 它必須在promise到rejected狀態(tài)后觸發(fā),promise的原因是它的第一個參數(shù)。
2.3.2.2. 它在一個promise到rejected之前禁止被觸發(fā)。
2.3.2.3. 它禁止被觸發(fā)多次。
2.2.4. onFulfilled或者onRejected只有在執(zhí)行上下文堆棧只有平臺代碼時才能被觸發(fā)。
2.2.5. onFulfilled和onRejected必須作為函數(shù)被調用(例如沒有this值)。
2.2.6. then方法可能在相同的promise中被調用多次。
2.2.6.1. 如果promise到了fullfilled狀態(tài),那么所有的onFulfilled回調函數(shù)都必須按照他們原有的順序進行調用執(zhí)行。
2.2.6.2. 如果promise到了rejected狀態(tài),那么所有的onRejected回調函數(shù)都必須按照他們原有的順序進行調用執(zhí)行。
2.2.7. then方法必須返回一個promise:
promise2 = promise1.then(onFulfilled, onRejected);
2.2.7.1. 如果onFulfilled或者onRejected方法返回一個值x,那么執(zhí)行promise的解析過程[[Resolve]](promise2, x)。
2.2.7.2. 如果onFulfilled或者onRejected方法拋出一個異常e,promise2必須使用e作為原因拒絕掉(rejected)。
2.2.7.3. 如果onFulfilled不是一個函數(shù)并且promise1到了fulfilled狀態(tài),那么promise2必須在與promise1的值相同的情況下轉換到fulfilled狀態(tài)。
2.2.7.4. 如果onRejected不是一個函數(shù)并且promise1到了rejected狀態(tài),那么promise2必須在與promise1的原因相同的情況下轉換到rejected狀態(tài)。
2.3. promise解析函數(shù)promise解析函數(shù)是一個輸入一個promise或者一個值的抽象的操作,我們表示為[[Resolve]](promise, x)。如果x是一個thenable對象,在假定x的行為至少有點像一個promise的情況下,它會嘗試讓promise轉換到x的狀態(tài)。否則,他會用x的值完成promise的狀態(tài)。
這種thenable對象的方式允許promise實現(xiàn)交互,只要他們暴露一個符合Promise/A+規(guī)范的then函數(shù)。它還允許Promise/A+的實現(xiàn)支持一個有合適的then方法的不兼容的實現(xiàn)。
運行[[Resolve]](promise, x),需要遵循以下步驟:
2.3.1. 如果promise和x指向同一個對象,那么用TypeError作為原因拒絕promise。
2.3.2. 如果x是一個promise,判斷它的狀態(tài):
2.3.2.1. 如果x是pending狀態(tài),promise保留pending狀態(tài)直到x變成fulfilled狀態(tài)或者rejected狀態(tài)。
2.3.2.2. 如果x是fulfilled狀態(tài),那么用同樣的值將整個promise完成。
2.3.2.3. 如果x是rejected狀態(tài),那么用同樣的原因拒絕promise。
2.3.3. 否則,如果x是一個對象或者函數(shù),
2.3.3.1. 讓then變成x.then。
2.3.3.2. 如果在檢測x.then這個屬性的結果時拋出一個異常e,把e作為原因拒絕promise。
2.3.3.3. 如果then是一個函數(shù),那么用x作為this來調用它,第一個參數(shù)是resolvePromise,第二個參數(shù)是rejectPromise:
2.3.3.3.1. 如果resolvePromise被值y調用,那么運行[[Resolve]](promise, y)。
2.3.3.3.2. 如果rejectPromise被原因r觸發(fā),那么用r來拒絕promise。
2.3.3.3.3. 如果resolvePromise和rejectPromise都被調用,或者使用相同的參數(shù)多次調用,那么第一次調用生效,其他之后的任何調用都忽略掉。
2.3.3.3.4. 如果在調用then方法時拋出了一個異常e,
2.3.3.3.4.1. 如果resolvePromise和rejectPromise已經(jīng)被調用了那么就忽略掉它。
2.3.3.3.4.2. 否則,使用e作為原因拒絕promise。
2.3.3.4. 如果then不是一個函數(shù),那么用x完成promise。
2.3.4. 如果x不是一個對象或者函數(shù),那么用x完成promise。
如果一個promise是通過在環(huán)形的thenable鏈中的一個thenable來完成的,如遞歸的[[Resolve]](promise, thenable)類型再次調用[[Resolve]](promise, thenable),遵循上述的規(guī)則會導致無窮遞歸。對這種遞歸情況的檢測并且使用TypeError作為原因進行拒絕,我們鼓勵實現(xiàn),但不要求。
3. 注意事項3.1. 在這里"平臺代碼"(platform code)意味著引擎,環(huán)境和promise實現(xiàn)代碼。在實踐中,這個要求確保了onFulfilled和onRejected是異步執(zhí)行的,then調用也是在循環(huán)之后,有一個新的堆棧信息。這可以通過一個宏任務(macro-task)機制例如setTimeout或者setImmediate來實現(xiàn),也可以通過一個微任務(micro-task)例如MutationObserver或者process.nextTick來實現(xiàn)。如果promise的實現(xiàn)考慮平臺代碼,那么它自己可能會帶一個任務執(zhí)行隊列或者“蹦床”來處理被調用情況。
3.2. 在嚴格模式下,this是在promise里面將會是undefined。在松散模型下,他代表的是全局對象。
3.3. 如果實現(xiàn)滿足所有要求的話,可以允許promise2 === promise1。每一個實現(xiàn)都應該表明是否支持promise2 === promise1,如果支持則是需要在什么條件下。
3.4. 通常來說,如果按照當前的實現(xiàn)方式,我們只能知道x是一個真的promise。這一條允許你在具體實現(xiàn)的使用過程中來判斷未知的promise的狀態(tài)。
3.5. 在程序中,首先存儲x.then的引用,其次測試這個引用,然后再調用這個引用,避免多次訪問x.then屬性。這樣的預防措施對于確保那些會在兩次訪問之間可能變化的屬性值獲取到一致的結果非常重要。
3.6. 實現(xiàn)中不應該對thenable調用鏈值設置任意深度限制,而是應該假設這個遞歸的限制值是無窮大。只有真正的循環(huán)才會導致TypeError;如果遇到了一個長度為無窮大的不同的thenable,保證在正確的行為下一直遞歸。
總結本文主要通過英文翻譯為中文的Promise/A+規(guī)范,讓大家了解了整個規(guī)范的全部內容。我會在下一篇博客中給大家?guī)砣绾螌崿F(xiàn)一個完全符合Promise/A+規(guī)范的Promise。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/97822.html
摘要:因此,當作為參數(shù)的執(zhí)行任意結果的回調函數(shù)時,就會將參數(shù)傳遞給外層的,執(zhí)行對應的回調函數(shù)。 背景 在上一篇博客[[譯]前端基礎知識儲備——Promise/A+規(guī)范](https://segmentfault.com/a/11...,我們介紹了Promise/A+規(guī)范的具體條目。在本文中,我們來選擇了promiz,讓大家來看下一個具體的Promise庫的內部代碼是如何運作的。 promiz...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。寫一個符合規(guī)范并可配合使用的寫一個符合規(guī)范并可配合使用的理解的工作原理采用回調函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個需求:在系統(tǒng)初始化時通過http獲取一個第三方服務器端的列表,第三方服務器提供了一個接口,可通過...
摘要:前端日報精選入門指南工作原理的新功能前端本地存儲數(shù)據(jù)庫實例教程模塊深入探究調查問卷中文譯掘金第期構建高性能展開收縮動畫譯代碼檢查工具對比前端之旅譯年了,這么多前端框架,你會怎樣選擇掘金譯不配置,不出事那些坑其一前端面試的大 2017-07-20 前端日報 精選 CSS入門指南-1:工作原理2017 Amsterdam CSS DayWebpack 3 的新功能:Scope Hoisti...
摘要:本文僅限瀏覽器環(huán)境測試,環(huán)境可能會不一致狀態(tài)一個實例只能處于三種狀態(tài)中的一種。每次創(chuàng)建的實例都會處于狀態(tài),并且只能由變?yōu)榛驙顟B(tài)??梢哉J為在實現(xiàn)里與中的都為解決程序。 前言 Promise作為ES6極為重要的一個特性,將我們從無限的回調地獄中解脫出來,變?yōu)殒準降木帉懟卣{,大大提高的代碼的可讀性。 使用Promise是極為簡單的,但只停留在會使用階段還是會讓我們不知不覺踩到一些坑的。本文會...
閱讀 2865·2021-09-10 10:50
閱讀 2213·2019-08-29 16:06
閱讀 3221·2019-08-29 11:02
閱讀 1117·2019-08-26 14:04
閱讀 2834·2019-08-26 13:24
閱讀 2331·2019-08-26 12:16
閱讀 574·2019-08-26 10:29
閱讀 3118·2019-08-23 18:33