摘要:英文官方文檔原文前言寫本文的目的,是為了更好的理解,通過(guò)解讀翻譯原文,逐行解析原文通過(guò)代碼一行一行實(shí)現(xiàn)。英中原因是一個(gè)值結(jié)果表明被拒絕的原因。英中在法律允許的范圍內(nèi),組織已放棄所有版權(quán)及規(guī)范的相關(guān)或相鄰權(quán)利。
英文官方文檔原文:https://promisesaplus.com/
前言
寫本文的目的,是為了更好的理解promise,通過(guò)解讀翻譯原文,逐行解析原文通過(guò)代碼一行一行實(shí)現(xiàn)。希望通過(guò)這篇文章,讓我們能對(duì)promise有更深入的了解。
首先介紹promises是什么,英文的字面意思是“承諾”的意思,接下來(lái)promises翻譯我沒(méi)有用承諾翻譯這個(gè)單詞,因?yàn)槲矣X(jué)得有些英文只是一個(gè)詞匯,還是直接用英文原文叫法好。
promise的是解決回調(diào)的問(wèn)題的,通過(guò)then的鏈?zhǔn)秸{(diào)用,讓我們能更清晰的理解閱讀代碼。下面直接看原文解讀:
英: An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.
中: 一個(gè)開(kāi)源標(biāo)準(zhǔn),可與JS互操作的Promises。由 implementers(語(yǔ)意創(chuàng)作這個(gè)promises的人或團(tuán)體)創(chuàng)作,implementers(實(shí)現(xiàn)者)。
英: A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.
中: 一個(gè)promise代表了異步操作的最終結(jié)果。與一個(gè)promise完成交互的主要方法是then方法,該方法會(huì)記錄回調(diào)以接收一個(gè)promise的成功返回值或者失敗的原因。
英: This specification details the behavior of the then method, providing an interoperable base which all Promises/A+ conformant promise implementations can be depended on to provide. As such, the specification should be considered very stable. Although the Promises/A+ organization may occasionally revise this specification with minor backward-compatible changes to address newly-discovered corner cases, we will integrate large or backward-incompatible changes only after careful consideration, discussion, and testing.
中: 本規(guī)范詳細(xì)的描述了then方法的行為,提供了一個(gè)可互操作的基礎(chǔ),所有的Promises / A +符合promise實(shí)現(xiàn)都可依賴提供。因此,本規(guī)范應(yīng)該被認(rèn)為是非常穩(wěn)定的。雖然Promises / A +組織偶爾會(huì)修改這個(gè)規(guī)范,但向后兼容更改次數(shù)較少,主要解決新發(fā)現(xiàn)的案例,我們只有在仔細(xì)考慮,討論以及測(cè)試之后才會(huì)整合大的改動(dòng)或者向后兼容的更改。
英: Historically, Promises/A+ clarifies the behavioral clauses of the earlier Promises/A proposal, extending it to cover de facto behaviors and omitting parts that are underspecified or problematic.
中: 歷史上,Promises / A +闡明了先前Promises / A提案的行為條款,將其擴(kuò)展為涵蓋事實(shí)上的行為,并略去了未指定或存在問(wèn)題的部分。
英: Finally, the core Promises/A+ specification does not deal with how to create, fulfill, or reject promises, choosing instead to focus on providing an interoperable then method. Future work in companion specifications may touch on these subjects.
中: 最后,核心Promises / A+規(guī)范不涉及如何創(chuàng)建,履行或拒絕promises,而是選擇專注于提供可互操作的方法。未來(lái)的配套規(guī)范工作可能涉及這些主題。
英: 1.Terminology 中: 1、術(shù)語(yǔ)英: 1.1 “promise” is an object or function with a then method whose behavior conforms to this specification.
中: 1.1 “promise”是一個(gè)對(duì)象或函數(shù),它的行為符合這個(gè)規(guī)范。
英: 1.2 “thenable” is an object or function that defines a then method.
中: 1.2 “thenable”是定義then方法的對(duì)象或函數(shù)。
英: 1.3 “value” is any legal JavaScript value (including undefined, a thenable, or a promise).
中: 1.3 “value”是任何合法的JavaScript值(包括undefined,thenable或promise)。
英: 1.4 “exception” is a value that is thrown using the throw statement.
中: 1.4 “異?!笔鞘褂胻hrow語(yǔ)句拋出的值。
英: 1.5 “reason” is a value that indicates why a promise was rejected.
中: 1.5 “原因”是一個(gè)值(結(jié)果)表明promise被拒絕的原因。
英: 2.Requirements2.1.Promise States中: 2、要求
2.1.Promise狀態(tài)
英: A promise must be in one of three states: pending, fulfilled, or rejected.
中: 一個(gè)promise必須包含初始態(tài), 成功(完成)態(tài), 或者失?。ň芙^)態(tài)這三個(gè)狀態(tài)中的一種。
英: 2.1.1 When pending, a promise:
2.1.1.1 may transition to either the fulfilled or rejected state.
中: 2.1.1 當(dāng)狀態(tài)是初始態(tài), promise:
2.1.1.1 可能轉(zhuǎn)換到成功態(tài)或失敗態(tài)。
英: 2.1.2. When fulfilled, a promise:
2.1.2.1. must not transition to any other state.
2.1.2.2. must have a value, which must not change.
中: 2.1.2 當(dāng)狀態(tài)是成功態(tài),promise:
2.1.2.1 不能更改成別的狀態(tài)。
2.1.2.2 必須有個(gè)不能更改的值(結(jié)果)
英: 2.1.3. When rejected, a promise:
2.1.3.1.must not transition to any other state.
2.1.3.2. must have a reason, which must not change.
中: 2.1.3 當(dāng)狀態(tài)是失敗態(tài),promise:
2.1.3.1. 不能更改成別的狀態(tài)。
2.1.3.2. 必須有個(gè)不能更改的失?。ㄥe(cuò)誤)原因
英: Here, “must not change” means immutable identity (i.e. ===), but does not imply deep immutability.
中: 上面,“不能改變”的意思是不可改變的狀態(tài)(即 ===),但并不意味著深不可變。
英: 2.2.The then Method
A promise must provide a then method to access its current or eventual value or reason.
A promise’s then method accepts two arguments:
promise.then(onFulfilled, onRejected)
中: 2.2 then方法
一個(gè)promise必須有一個(gè)then方法來(lái)獲取成功的值(結(jié)果)或失?。ㄥe(cuò)誤)的原因。
一個(gè)promise方法接收兩個(gè)參數(shù):
promise.then(onFulfilled, onRejected)
英: 2.2.1. Both onFulfilled and onRejected are optional arguments:
2.2.1.1.If onFulfilled is not a function, it must be ignored.
2.2.1.2.If onRejected is not a function, it must be ignored.
中: 2.2.1. onFulfilled和onRejected都是可選參數(shù):
2.2.1.1 如果onFulfilled不是函數(shù),則必須忽略它。
2.2.1.2 如果onRejected不是函數(shù),則必須忽略它。
英: 2.2.2 If onFulfilled is a function:
2.2.2.1.it must be called after promise is fulfilled, with promise’s value as its first argument.
2.2.2.2.it must not be called before promise is fulfilled.
2.2.2.3.it must not be called more than once.
中: 2.2.2 如果onFulfilled是一個(gè)函數(shù):
2.2.2.1 必須在promise執(zhí)行完成后調(diào)用,promise的返回值作為第一個(gè)參數(shù)。
2.2.2.2 在promise執(zhí)行前不得調(diào)用。
2.2.2.3 只能調(diào)用一次。
英: 2.2.3.If onRejected is a function,
2.2.3.1.it must be called after promise is rejected, with promise’s reason as its first argument.
2.2.3.2.it must not be called before promise is rejected.
2.2.3.3.it must not be called more than once.
中: 2.2.3 如果onRejected是一個(gè)函數(shù):
2.2.3.1 必須在promise執(zhí)行完成后調(diào)用,promise的錯(cuò)誤原因作為第一個(gè)參數(shù)。
2.2.3.2 在promise執(zhí)行前不得調(diào)用。
2.2.3.3 只能調(diào)用一次。
英: 2.2.4.onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].
中: 2.2.4 在執(zhí)行上下文堆棧僅包含平臺(tái)代碼之前,不能調(diào)用onFulfilled或onRejected。[3.1]。
英: 2.2.5 onFulfilled and onRejected must be called as functions (i.e. with no this value). [3.2]
中: onFulfilled和onRejected必須是函數(shù)(即 沒(méi)有這個(gè)值)。[3.2]
英: 2.2.6.then may be called multiple times on the same promise.
2.2.6.1.If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.
2.2.6.2.If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.
中: 2.2.6 then方法可能會(huì)在相同的promise被多次調(diào)用。
2.2.6.1 如果/當(dāng)promise成功時(shí),所有各自的onFulfilled回調(diào)必須按照其始發(fā)調(diào)用的順序執(zhí)行。
2.2.6.2 如果/當(dāng)promise失敗時(shí),所有各自的onRejected回調(diào)必須按照其始發(fā)調(diào)用的順序執(zhí)行。
英: 2.2.7. then must return a promise [3.3].
promise2 = promise1.then(onFulfilled, onRejected);
2.2.7.1.If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).
2.2.7.2.If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.
2.2.7.3.If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.
2.2.7.4.If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.
中: 2.2.7 then方法必須返回一個(gè)promise。[3.3]
例如:promise2 = promise1.then(onFulfilled, onRejected);
2.2.7.1 如果onFulfilled或onRejected返回一個(gè)值(結(jié)果)x,運(yùn)行Promise的解決程序 [[Resolve]](promise2,x)。
2.2.7.2 如果onFulfilled或onRejected引發(fā)異常e,promise2必須以e作為拒絕原因。
2.2.7.3 如果onFulfilled不是一個(gè)函數(shù)并且promise1是被成功,那么promise2必須用與promise1相同的值執(zhí)行。
2.2.7.4 如果onRejected不是函數(shù)并且promise1是被失敗,那么promise2必須用與promise1相同的失敗原因。
英: 2.3.The Promise Resolution Procedure
中: 2.3 Promise的解決程序
英: The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.
中: Promise的解決程序是一個(gè)抽象操作,取得輸入的promise和一個(gè)值(結(jié)果),我們表示為 [[Resolve]](promise, x)。
[[Resolve]](promise, x)的意思是創(chuàng)建一個(gè)方法Resolve方法執(zhí)行時(shí)傳入兩個(gè)參數(shù)promise和x(promise成功態(tài)時(shí)返回的值)。如果x是一個(gè)thenable(見(jiàn)上文術(shù)語(yǔ)1.2),它試圖創(chuàng)造一個(gè)promise采用x的狀態(tài),假設(shè)x的行為至少貌似promise。否則,它用x值執(zhí)行promise。
英: This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.
中: 對(duì)thenable的這種處理允許promise實(shí)現(xiàn)交互操作,只要它們暴露Promise / A +兼容的方法即可。 它還允許Promises / A +實(shí)現(xiàn)通過(guò)合理的方法“吸收”不合格的實(shí)現(xiàn)。
英: To run [[Resolve]](promise, x), perform the following steps:
2.3.1. if promise and x refer to the same object, reject promise with a TypeError as the reason.
中: 去運(yùn)行 [[Resolve]](promise, x),需執(zhí)行以下步驟:
2.3.1 如果promise和x引用同一個(gè)對(duì)象,則以TypeError為原因拒絕promise。
英: 2.3.2. If x is a promise, adopt its state [3.4]:
2.3.2.1.If x is pending, promise must remain pending until x is fulfilled or rejected.
2.3.2.2.If/when x is fulfilled, fulfill promise with the same value.
2.3.2.3.If/when x is rejected, reject promise with the same reason.
中: 2.3.2 如果x是一個(gè)promise,采用它的狀態(tài)【3.4】:
2.3.2.1 如果x是初始態(tài),promise必須保持初始態(tài)(即遞歸執(zhí)行這個(gè)解決程序),直到x被成功或被失敗。(即,直到resolve或者reject執(zhí)行)
2.3.2.2 如果/當(dāng)x被成功時(shí),用相同的值(結(jié)果)履行promise。
2.3.2.3 如果/當(dāng)x被失敗時(shí),用相同的錯(cuò)誤原因履行promise。
英: 2.3.3.Otherwise, if x is an object or function,
2.3.3.1.Let then be x.then. [3.5]
2.3.3.2.If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
2.3.3.3.If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise, where:
2.3.3.3.1.If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
2.3.3.3.2.If/when rejectPromise is called with a reason r, reject promise with r.
2.3.3.3.3.If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
2.3.3.3.4.If calling then throws an exception e,
2.3.3.3.4.1.If resolvePromise or rejectPromise have been called, ignore it.
2.3.3.3.4.2.Otherwise, reject promise with e as the reason.
2.3.3.4.If then is not a function, fulfill promise with x.
中: 2.3.3 否則,如果x是一個(gè)對(duì)象或函數(shù),
2.3.3.1 讓then等于x.then?!?.5】
2.3.3.2 如果x.then導(dǎo)致拋出異常e,拒絕promise并用e作為失敗原因。
2.3.3.3 如果then是一個(gè)函數(shù),則使用x作為此參數(shù)調(diào)用它,第一個(gè)參數(shù)resolvePromise,第二個(gè)參數(shù)rejectPromise,其中:
2.3.3.3.1 如果使用值(結(jié)果)y調(diào)用resolvePromise,運(yùn)行[[Resolve]](promise,y)我的解決程序的名字是resolveExecutor。
2.3.3.3.2 如果使用拒絕原因r調(diào)用resolvePromise,運(yùn)行reject(r)。
2.3.3.3.3 如果resolvePromise和rejectPromise都被調(diào)用,或者對(duì)同一個(gè)參數(shù)進(jìn)行多次調(diào)用,則第一次調(diào)用優(yōu)先,并且任何進(jìn)一步的調(diào)用都會(huì)被忽略。
2.3.3.3.4 如果調(diào)用then方法拋出異常e,
2.3.3.3.4.1 如果resolvePromise或rejectPromise已經(jīng)調(diào)用了,則忽略它。
2.3.3.3.4.2 否則,以e作為失敗原因拒絕promise。
2.3.3.4 如果then不是一個(gè)對(duì)象或者函數(shù),則用x作為值(結(jié)果)履行promise。
英: 2.3.4.If x is not an object or function, fulfill promise with x.
If a promise is resolved with a thenable that participates in a circular thenable chain, such that the recursive nature of [[Resolve]](promise, thenable) eventually causes [[Resolve]](promise, thenable) to be called again, following the above algorithm will lead to infinite recursion. Implementations are encouraged, but not required, to detect such recursion and reject promise with an informative TypeError as the reason. [3.6]
中: 2.3.4 如果x不是一個(gè)對(duì)象或函數(shù),則用x作為值履行promise。
如果一個(gè)primse是通過(guò)一個(gè)thenable參與一個(gè)循環(huán)的可鏈接表達(dá)式來(lái)解決的thenable鏈,那么[[Resolve]](promise,thenable)的遞歸性質(zhì)最終會(huì)導(dǎo)致[[Resolve]](promise,thenable)被再次調(diào)用, 上述算法將導(dǎo)致無(wú)限遞歸。 支持這種實(shí)現(xiàn),但不是必需的,來(lái)檢測(cè)這種遞歸并以一個(gè)信息性的TypeError為理由拒絕promise?!?.6】
3.1.Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.中: 3.注釋
3.1 這里的“平臺(tái)代碼”是指引擎,環(huán)境和primise實(shí)現(xiàn)代碼。在實(shí)踐中,這個(gè)要求確保onFulfilled和onRejected異步執(zhí)行,在事件循環(huán)開(kāi)始之后then被調(diào)用,和一個(gè)新的堆棧。這可以使用諸如setTimeout或setImmediate之類的“宏任務(wù)”機(jī)制,或者使用諸如MutationObserver或process.nextTick的“微任務(wù)”機(jī)制來(lái)實(shí)現(xiàn)。由于promise實(shí)現(xiàn)被認(rèn)為是經(jīng)過(guò)深思熟慮的平臺(tái)代碼,因此它本身可能包含調(diào)用處理程序的任務(wù)調(diào)度隊(duì)列或或稱為“trampoline”(可重用的)的處理程序。
英: 3.2.That is, in strict mode this will be undefined inside of them; in sloppy mode, it will be the global object.
中: 3.2 即:在嚴(yán)格模式下是undefined;非嚴(yán)格模式下是全局對(duì)象。
英: 3.3.Implementations may allow promise2 === promise1, provided the implementation meets all requirements. Each implementation should document whether it can produce promise2 === promise1 and under what conditions.
中: 3.3 實(shí)現(xiàn)可能會(huì)允許promise2 === promise1, 前提是實(shí)現(xiàn)符合所有的要求。每個(gè)實(shí)現(xiàn)應(yīng)該記錄它是否可以產(chǎn)生promise2 === promise1以及在什么條件下。
英: 3.4.Generally, it will only be known that x is a true promise if it comes from the current implementation. This clause allows the use of implementation-specific means to adopt the state of known-conformant promises.
中: 3.4 通常,只有當(dāng)它是來(lái)自當(dāng)前的實(shí)現(xiàn)時(shí)才會(huì)知道x是一個(gè)真正的promise。該條款允許使用具體實(shí)現(xiàn)方法來(lái)采用已知符合性promise的狀態(tài)。
英: 3.5.This procedure of first storing a reference to x.then, then testing that reference, and then calling that reference, avoids multiple accesses to the x.then property. Such precautions are important for ensuring consistency in the face of an accessor property, whose value could change between retrievals.
中: 3.5 首先存儲(chǔ)對(duì)x.then的引用,然后測(cè)試和調(diào)用該引用,避免多次使用x.then屬性。這樣的注意事項(xiàng)對(duì)于確保訪問(wèn)器的屬的一致性性非常重要,其值(結(jié)果)可能在取回時(shí)改變。
英: 3.6.Implementations should not set arbitrary limits on the depth of thenable chains, and assume that beyond that arbitrary limit the recursion will be infinite. Only true cycles should lead to a TypeError; if an infinite chain of distinct thenables is encountered, recursing forever is the correct behavior.
中: 3.6 實(shí)現(xiàn)不應(yīng)該對(duì)thenable鏈做任意設(shè)定限制,假定超出該任意設(shè)定限制遞歸將是無(wú)限的。只有真正的循環(huán)才導(dǎo)致TypeError; 如果遇到不同的thenables的無(wú)限鏈,一直遞歸是正確的行為。
英: To the extent possible under law, the Promises/A+ organization has waived all copyright and related or neighboring rights to Promises/A+ Promise Specification. This work is published from: United States.
中: 在法律允許的范圍內(nèi),Promises / A +組織已放棄所有版權(quán)及Promises / A +規(guī)范的相關(guān)或相鄰權(quán)利。本作品發(fā)表于:美國(guó)。
---------以上是原文翻譯
啥也別說(shuō)上代碼
class MyPromise { constructor(executor) { //緩存this ;let self = this //設(shè)置初始態(tài) ;self.status = "pending" //定義成功的值默認(rèn)undefined ;self.value = undefined //定義失敗的原因默認(rèn)undefined ;self.reason = undefined //定義成功的回調(diào)數(shù)組 ;self.onResolvedCallbacks = [] //定義失敗的回調(diào)數(shù)組 ;self.onRejectedCallbacks = [] //定義成功時(shí)執(zhí)行的函數(shù) ;let resolve = value => { ;if (value instanceof MyPromise) return value.then(resolve, reject) //異步執(zhí)行成功回調(diào) ;setTimeout(() => { if (self.status === "pending") { //把狀態(tài)改為成功態(tài) ;self.status = "fulfilled" //保存成功的值 ;self.value = value //遍歷執(zhí)行每個(gè)成功的回調(diào) ;self.onResolvedCallbacks.forEach(onFulfilled => onFulfilled(value)) } }) } //定義失敗時(shí)執(zhí)行的函數(shù) ;let reject = reason => { //異步執(zhí)行失敗回調(diào) setTimeout(() => { if (self.status === "pending") { //把狀態(tài)改為失敗態(tài) ;self.status = "rejected" //保存失敗的原因 ;self.reason = reason //遍歷執(zhí)行每個(gè)失敗的回調(diào) ;self.onRejectedCallbacks.forEach(onRejected => onRejected(reason)) } }) } //由于調(diào)用executor這個(gè)方法有可能異常,需要將捕獲的異常reject出去 ;try { //運(yùn)行傳進(jìn)來(lái)的函數(shù)把成功和失敗的方法傳進(jìn)去 ;executor(resolve, reject) } catch (e) { ;reject(e) } } /** * @param {Function} onFulfilled //值的穿透,默認(rèn)值往后傳 * @param {Function} onRejected //默認(rèn)把失敗原因往后拋 */ then(onFulfilled = value => value, onRejected = reason => {throw reason}) { //緩存this,定義promise2 ;let self = this ;let promise2 //promise主要解決程序,也是promise的難點(diǎn) ;let resolveExecutor = (promise2, x, resolve, reject) => { // 定義個(gè)標(biāo)識(shí) promise2是否已經(jīng)resolve 或 reject了 ;let isThenCalled = false // 2.3.1 如果promise和x引用同一個(gè)對(duì)象,則以TypeError為原因拒絕promise。 ;if (promise2 === x) return reject(new TypeError("循環(huán)引用?。?!")) // 2.3.2 如果x是一個(gè)promise,采用它的狀態(tài)【3.4 ;if (x instanceof MyPromise) { /** * 2.3.2.1 如果x是初始態(tài),promise必須保持初始態(tài)(即遞歸執(zhí)行這個(gè)解決程序),直到x被成功或被失敗。(即,直到resolve或者reject執(zhí)行) */ if (x.status === "pending") { x.then(function(y) { ;resolveExecutor(promise2, y, resolve, reject) }, reject) } else { // 2.3.2.2 如果/當(dāng)x被成功時(shí),用相同的值(結(jié)果)履行promise。 // 2.3.2.3 如果/當(dāng)x被失敗時(shí),用相同的錯(cuò)誤原因履行promise。 ;x.then(resolve, reject) } } else if (x !== null && (typeof x === "object" || typeof x === "function")) { // 2.3.3 否則,如果x是一個(gè)對(duì)象或函數(shù), try { // 2.3.3.1 讓then等于x.then。【3.5】 ;let then = x.then if (typeof then === "function") { //2.3.3.3.3 如果resolvePromise和rejectPromise都被調(diào)用,或者對(duì)同一個(gè)參數(shù)進(jìn)行多次調(diào)用,則第一次調(diào)用優(yōu)先,并且任何進(jìn)一步的調(diào)用都會(huì)被忽略。 ;let resolvePromise = y => { //如果promise2已經(jīng)成功或失敗了,就return掉 ;if (isThenCalled) return ;isThenCalled = true //2.3.3.3.1 如果使用值(結(jié)果)y調(diào)用resolvePromise,運(yùn)行[[Resolve]](promise,y)我的解決程序的名字是resolveExecutor,也就是遞歸調(diào)用。 ;resolveExecutor(promise2, y, resolve, reject) } ;let rejectPromise = r => { //如果promise2已經(jīng)成功或失敗了,就return掉 ;if (isThenCalled) return ;isThenCalled = true //2.3.3.3.2 如果使用拒絕原因r調(diào)用resolvePromise,運(yùn)行reject(r)。 ;reject(r) }; // 2.3.3.3 如果then是一個(gè)函數(shù),則使用x作為此參數(shù)調(diào)用它,第一個(gè)參數(shù)resolveExecutor,第二個(gè)參數(shù)rejectPromise,其中 ;then.call(x, resolvePromise, rejectPromise) } else { //到此的話x不是一個(gè)thenable對(duì)象,那直接把它當(dāng)成值resolve promise2就可以了 ;resolve(x) } } catch (e) { //2.3.3.3.4 如果調(diào)用then方法拋出異常e, //2.3.3.3.4.1 如果resolvePromise或rejectPromise已經(jīng)調(diào)用了,則忽略它。 ;if (isThenCalled) return ;isThenCalled = true //2.3.3.2 如果x.then導(dǎo)致拋出異常e,拒絕promise并用e作為失敗原因 //2.3.3.3.4.2 否則,以e作為失敗原因拒絕promise ;reject(e) } } else { //2.3.3.4 如果then不是一個(gè)對(duì)象或者函數(shù),則用x作為值(結(jié)果)履行promise。 ;resolve(x) } }; if (self.status === "fulfilled") { //2.2.7 return (promise2 = new MyPromise((resolve, reject) => { //2.2.4 在執(zhí)行上下文堆棧僅包含平臺(tái)代碼之前,不能調(diào)用onFulfilled或onRejected。[3.1]。 //3.1 這里的“平臺(tái)代碼”是指引擎,環(huán)境和primise實(shí)現(xiàn)代碼。在實(shí)踐中,這個(gè)要求確保onFulfilled和onRejected異步執(zhí)行,在事件循環(huán)開(kāi)始之后then被調(diào)用,和一個(gè)新的堆棧。這可以使用諸如setTimeout或setImmediate之類的“宏任務(wù)”機(jī)制,或者使用諸如MutationObserver或process.nextTick的“微任務(wù)”機(jī)制來(lái)實(shí)現(xiàn)。由于promise實(shí)現(xiàn)被認(rèn)為是經(jīng)過(guò)深思熟慮的平臺(tái)代碼,因此它本身可能包含調(diào)用處理程序的任務(wù)調(diào)度隊(duì)列或或稱為“trampoline”(可重用的)的處理程序。 //讓onFulfilled異步執(zhí)行 setTimeout(() => { try { ;let x = onFulfilled(self.value) ;resolveExecutor(promise2, x, resolve, reject) } catch (e) { ;reject(e) } }) })) } if (self.status === "rejected") { return (promise2 = new MyPromise((resolve, reject) => { //2.2.4 在執(zhí)行上下文堆棧僅包含平臺(tái)代碼之前,不能調(diào)用onFulfilled或onRejected。[3.1]。 //3.1 這里的“平臺(tái)代碼”是指引擎,環(huán)境和primise實(shí)現(xiàn)代碼。在實(shí)踐中,這個(gè)要求確保onFulfilled和onRejected異步執(zhí)行,在事件循環(huán)開(kāi)始之后then被調(diào)用,和一個(gè)新的堆棧。這可以使用諸如setTimeout或setImmediate之類的“宏任務(wù)”機(jī)制,或者使用諸如MutationObserver或process.nextTick的“微任務(wù)”機(jī)制來(lái)實(shí)現(xiàn)。由于promise實(shí)現(xiàn)被認(rèn)為是經(jīng)過(guò)深思熟慮的平臺(tái)代碼,因此它本身可能包含調(diào)用處理程序的任務(wù)調(diào)度隊(duì)列或或稱為“trampoline”(可重用的)的處理程序。 //讓onFulfilled異步執(zhí)行 setTimeout(() => { try { ;let x = onRejected(self.reason) ;resolveExecutor(promise2, x, resolve, reject) } catch (e) { ;reject(e) } }) })) } if (self.status === "pending") { return (promise2 = new MyPromise((resolve, reject) => { self.onResolvedCallbacks.push(() => { try { ;let x = onFulfilled(self.value) ;resolveExecutor(promise2, x, resolve, reject) } catch (e) { ;reject(e) } }); self.onRejectedCallbacks.push(() => { try { ;let x = onRejected(self.reason) ;resolveExecutor(promise2, x, resolve, reject) } catch (e) { ;reject(e) } }) })) } } catch(onRejected) { ;this.then(null, onRejected) } //立即成功的promise static resolve(value) { return new MyPromise(resolve => { ;resolve(value) }) } //立即失敗的promise static reject(reason) { return new MyPromise((resolve, reject) => { ;reject(reason) }) } //promise all方法,只要有一個(gè)失敗就失敗了。 static all(promises) { return new MyPromise((resolve, reject) => { ;let len = promises.length ;let resolveAry = [] ;let count = 0 for (let i = 0; i < len; i++) { promises[i].then(value => { ;resolveAry[i] = value ;if (++count === len) resolve(resolveAry) }, reject) } }) } //promise race方法,看resolve和reject哪個(gè)先返回,就取哪個(gè)值,成功就取成功的value,失敗就取失敗的reason。 static race(promises) { return new MyPromise((resolve, reject) => { for (let i = 0, l = promises.length; i < l; i++) { ;promises[i].then(resolve, reject) } }) } } module.exports = MyPromise;
~~~ 如有不妥之處,歡迎大家留言指正,如覺(jué)得好請(qǐng)關(guān)注,點(diǎn)贊,轉(zhuǎn)發(fā)請(qǐng)注明出處,謝謝! ~~~
郵箱:gameness1212@163.com
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/93067.html
摘要:從最開(kāi)始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來(lái)處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問(wèn)題描述 在開(kāi)發(fā)過(guò)程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過(guò)http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過(guò)...
摘要:的翻譯文檔由的維護(hù)很多人說(shuō),阮老師已經(jīng)有一本關(guān)于的書了入門,覺(jué)得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開(kāi)發(fā)過(guò)程中,顯得越來(lái)越重要。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 Github版本:Front-End Resource Collection 前端相關(guān)資源匯總 學(xué)習(xí)指導(dǎo) 精華文章 Web前端的路該怎么走?:文章超長(zhǎng),但是干貨超級(jí)多,值得反復(fù)精讀! 聽(tīng)說(shuō)2017你想寫前端?:適合于已經(jīng)度過(guò)了小白階...
摘要:工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 Github版本:Front-End Resource Collection 前端相關(guān)資源匯總 學(xué)習(xí)指導(dǎo) 精華文章 Web前端的路該怎么走?:文章超長(zhǎng),但是干貨超級(jí)多,值得反復(fù)精讀! 聽(tīng)說(shuō)2017你想寫前端?:適合于已經(jīng)度過(guò)了小白階...
摘要:工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 工作原因,最近一年斷斷續(xù)續(xù)寫了一點(diǎn)前端代碼,收集整理了一些資料,和大家共享。 Github版本:Front-End Resource Collection 前端相關(guān)資源匯總 學(xué)習(xí)指導(dǎo) 精華文章 Web前端的路該怎么走?:文章超長(zhǎng),但是干貨超級(jí)多,值得反復(fù)精讀! 聽(tīng)說(shuō)2017你想寫前端?:適合于已經(jīng)度過(guò)了小白階...
閱讀 1136·2021-11-22 15:33
閱讀 3442·2021-11-08 13:20
閱讀 1483·2021-09-22 10:55
閱讀 2115·2019-08-29 11:08
閱讀 846·2019-08-26 12:24
閱讀 3146·2019-08-23 17:15
閱讀 2303·2019-08-23 16:12
閱讀 2014·2019-08-23 16:09