摘要:英文官方文檔原文前言寫本文的目的,是為了更好的理解,通過解讀翻譯原文,逐行解析原文通過代碼一行一行實現(xiàn)。英中原因是一個值結(jié)果表明被拒絕的原因。英中在法律允許的范圍內(nèi),組織已放棄所有版權(quán)及規(guī)范的相關(guān)或相鄰權(quán)利。
英文官方文檔原文:https://promisesaplus.com/
前言
寫本文的目的,是為了更好的理解promise,通過解讀翻譯原文,逐行解析原文通過代碼一行一行實現(xiàn)。希望通過這篇文章,讓我們能對promise有更深入的了解。
首先介紹promises是什么,英文的字面意思是“承諾”的意思,接下來promises翻譯我沒有用承諾翻譯這個單詞,因為我覺得有些英文只是一個詞匯,還是直接用英文原文叫法好。
promise的是解決回調(diào)的問題的,通過then的鏈式調(diào)用,讓我們能更清晰的理解閱讀代碼。下面直接看原文解讀:
英: An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.
中: 一個開源標準,可與JS互操作的Promises。由 implementers(語意創(chuàng)作這個promises的人或團體)創(chuàng)作,implementers(實現(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.
中: 一個promise代表了異步操作的最終結(jié)果。與一個promise完成交互的主要方法是then方法,該方法會記錄回調(diào)以接收一個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ī)范詳細的描述了then方法的行為,提供了一個可互操作的基礎(chǔ),所有的Promises / A +符合promise實現(xiàn)都可依賴提供。因此,本規(guī)范應(yīng)該被認為是非常穩(wěn)定的。雖然Promises / A +組織偶爾會修改這個規(guī)范,但向后兼容更改次數(shù)較少,主要解決新發(fā)現(xiàn)的案例,我們只有在仔細考慮,討論以及測試之后才會整合大的改動或者向后兼容的更改。
英: 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提案的行為條款,將其擴展為涵蓋事實上的行為,并略去了未指定或存在問題的部分。
英: 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,而是選擇專注于提供可互操作的方法。未來的配套規(guī)范工作可能涉及這些主題。
英: 1.Terminology 中: 1、術(shù)語英: 1.1 “promise” is an object or function with a then method whose behavior conforms to this specification.
中: 1.1 “promise”是一個對象或函數(shù),它的行為符合這個規(guī)范。
英: 1.2 “thenable” is an object or function that defines a then method.
中: 1.2 “thenable”是定義then方法的對象或函數(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 “異常”是使用throw語句拋出的值。
英: 1.5 “reason” is a value that indicates why a promise was rejected.
中: 1.5 “原因”是一個值(結(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.
中: 一個promise必須包含初始態(tài), 成功(完成)態(tài), 或者失敗(拒絕)態(tài)這三個狀態(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 必須有個不能更改的值(結(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. 必須有個不能更改的失敗(錯誤)原因
英: 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方法
一個promise必須有一個then方法來獲取成功的值(結(jié)果)或失敗(錯誤)的原因。
一個promise方法接收兩個參數(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是一個函數(shù):
2.2.2.1 必須在promise執(zhí)行完成后調(diào)用,promise的返回值作為第一個參數(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是一個函數(shù):
2.2.3.1 必須在promise執(zhí)行完成后調(diào)用,promise的錯誤原因作為第一個參數(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í)行上下文堆棧僅包含平臺代碼之前,不能調(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ù)(即 沒有這個值)。[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方法可能會在相同的promise被多次調(diào)用。
2.2.6.1 如果/當(dāng)promise成功時,所有各自的onFulfilled回調(diào)必須按照其始發(fā)調(diào)用的順序執(zhí)行。
2.2.6.2 如果/當(dāng)promise失敗時,所有各自的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方法必須返回一個promise。[3.3]
例如:promise2 = promise1.then(onFulfilled, onRejected);
2.2.7.1 如果onFulfilled或onRejected返回一個值(結(jié)果)x,運行Promise的解決程序 [[Resolve]](promise2,x)。
2.2.7.2 如果onFulfilled或onRejected引發(fā)異常e,promise2必須以e作為拒絕原因。
2.2.7.3 如果onFulfilled不是一個函數(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的解決程序是一個抽象操作,取得輸入的promise和一個值(結(jié)果),我們表示為 [[Resolve]](promise, x)。
[[Resolve]](promise, x)的意思是創(chuàng)建一個方法Resolve方法執(zhí)行時傳入兩個參數(shù)promise和x(promise成功態(tài)時返回的值)。如果x是一個thenable(見上文術(shù)語1.2),它試圖創(chuàng)造一個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.
中: 對thenable的這種處理允許promise實現(xiàn)交互操作,只要它們暴露Promise / A +兼容的方法即可。 它還允許Promises / A +實現(xiàn)通過合理的方法“吸收”不合格的實現(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.
中: 去運行 [[Resolve]](promise, x),需執(zhí)行以下步驟:
2.3.1 如果promise和x引用同一個對象,則以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是一個promise,采用它的狀態(tài)【3.4】:
2.3.2.1 如果x是初始態(tài),promise必須保持初始態(tài)(即遞歸執(zhí)行這個解決程序),直到x被成功或被失敗。(即,直到resolve或者reject執(zhí)行)
2.3.2.2 如果/當(dāng)x被成功時,用相同的值(結(jié)果)履行promise。
2.3.2.3 如果/當(dāng)x被失敗時,用相同的錯誤原因履行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是一個對象或函數(shù),
2.3.3.1 讓then等于x.then。【3.5】
2.3.3.2 如果x.then導(dǎo)致拋出異常e,拒絕promise并用e作為失敗原因。
2.3.3.3 如果then是一個函數(shù),則使用x作為此參數(shù)調(diào)用它,第一個參數(shù)resolvePromise,第二個參數(shù)rejectPromise,其中:
2.3.3.3.1 如果使用值(結(jié)果)y調(diào)用resolvePromise,運行[[Resolve]](promise,y)我的解決程序的名字是resolveExecutor。
2.3.3.3.2 如果使用拒絕原因r調(diào)用resolvePromise,運行reject(r)。
2.3.3.3.3 如果resolvePromise和rejectPromise都被調(diào)用,或者對同一個參數(shù)進行多次調(diào)用,則第一次調(diào)用優(yōu)先,并且任何進一步的調(diào)用都會被忽略。
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不是一個對象或者函數(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不是一個對象或函數(shù),則用x作為值履行promise。
如果一個primse是通過一個thenable參與一個循環(huán)的可鏈接表達式來解決的thenable鏈,那么[[Resolve]](promise,thenable)的遞歸性質(zhì)最終會導(dǎo)致[[Resolve]](promise,thenable)被再次調(diào)用, 上述算法將導(dǎo)致無限遞歸。 支持這種實現(xiàn),但不是必需的,來檢測這種遞歸并以一個信息性的TypeError為理由拒絕promise。【3.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 這里的“平臺代碼”是指引擎,環(huán)境和primise實現(xiàn)代碼。在實踐中,這個要求確保onFulfilled和onRejected異步執(zhí)行,在事件循環(huán)開始之后then被調(diào)用,和一個新的堆棧。這可以使用諸如setTimeout或setImmediate之類的“宏任務(wù)”機制,或者使用諸如MutationObserver或process.nextTick的“微任務(wù)”機制來實現(xiàn)。由于promise實現(xiàn)被認為是經(jīng)過深思熟慮的平臺代碼,因此它本身可能包含調(diào)用處理程序的任務(wù)調(diào)度隊列或或稱為“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 即:在嚴格模式下是undefined;非嚴格模式下是全局對象。
英: 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 實現(xiàn)可能會允許promise2 === promise1, 前提是實現(xiàn)符合所有的要求。每個實現(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)它是來自當(dāng)前的實現(xiàn)時才會知道x是一個真正的promise。該條款允許使用具體實現(xiàn)方法來采用已知符合性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 首先存儲對x.then的引用,然后測試和調(diào)用該引用,避免多次使用x.then屬性。這樣的注意事項對于確保訪問器的屬的一致性性非常重要,其值(結(jié)果)可能在取回時改變。
英: 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 實現(xiàn)不應(yīng)該對thenable鏈做任意設(shè)定限制,假定超出該任意設(shè)定限制遞歸將是無限的。只有真正的循環(huán)才導(dǎo)致TypeError; 如果遇到不同的thenables的無限鏈,一直遞歸是正確的行為。
英: 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ā)表于:美國。
---------以上是原文翻譯
啥也別說上代碼
class MyPromise { constructor(executor) { //緩存this ;let self = this //設(shè)置初始態(tài) ;self.status = "pending" //定義成功的值默認undefined ;self.value = undefined //定義失敗的原因默認undefined ;self.reason = undefined //定義成功的回調(diào)數(shù)組 ;self.onResolvedCallbacks = [] //定義失敗的回調(diào)數(shù)組 ;self.onRejectedCallbacks = [] //定義成功時執(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í)行每個成功的回調(diào) ;self.onResolvedCallbacks.forEach(onFulfilled => onFulfilled(value)) } }) } //定義失敗時執(zhí)行的函數(shù) ;let reject = reason => { //異步執(zhí)行失敗回調(diào) setTimeout(() => { if (self.status === "pending") { //把狀態(tài)改為失敗態(tài) ;self.status = "rejected" //保存失敗的原因 ;self.reason = reason //遍歷執(zhí)行每個失敗的回調(diào) ;self.onRejectedCallbacks.forEach(onRejected => onRejected(reason)) } }) } //由于調(diào)用executor這個方法有可能異常,需要將捕獲的異常reject出去 ;try { //運行傳進來的函數(shù)把成功和失敗的方法傳進去 ;executor(resolve, reject) } catch (e) { ;reject(e) } } /** * @param {Function} onFulfilled //值的穿透,默認值往后傳 * @param {Function} onRejected //默認把失敗原因往后拋 */ then(onFulfilled = value => value, onRejected = reason => {throw reason}) { //緩存this,定義promise2 ;let self = this ;let promise2 //promise主要解決程序,也是promise的難點 ;let resolveExecutor = (promise2, x, resolve, reject) => { // 定義個標識 promise2是否已經(jīng)resolve 或 reject了 ;let isThenCalled = false // 2.3.1 如果promise和x引用同一個對象,則以TypeError為原因拒絕promise。 ;if (promise2 === x) return reject(new TypeError("循環(huán)引用!!!")) // 2.3.2 如果x是一個promise,采用它的狀態(tài)【3.4 ;if (x instanceof MyPromise) { /** * 2.3.2.1 如果x是初始態(tài),promise必須保持初始態(tài)(即遞歸執(zhí)行這個解決程序),直到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被成功時,用相同的值(結(jié)果)履行promise。 // 2.3.2.3 如果/當(dāng)x被失敗時,用相同的錯誤原因履行promise。 ;x.then(resolve, reject) } } else if (x !== null && (typeof x === "object" || typeof x === "function")) { // 2.3.3 否則,如果x是一個對象或函數(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)用,或者對同一個參數(shù)進行多次調(diào)用,則第一次調(diào)用優(yōu)先,并且任何進一步的調(diào)用都會被忽略。 ;let resolvePromise = y => { //如果promise2已經(jīng)成功或失敗了,就return掉 ;if (isThenCalled) return ;isThenCalled = true //2.3.3.3.1 如果使用值(結(jié)果)y調(diào)用resolvePromise,運行[[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,運行reject(r)。 ;reject(r) }; // 2.3.3.3 如果then是一個函數(shù),則使用x作為此參數(shù)調(diào)用它,第一個參數(shù)resolveExecutor,第二個參數(shù)rejectPromise,其中 ;then.call(x, resolvePromise, rejectPromise) } else { //到此的話x不是一個thenable對象,那直接把它當(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不是一個對象或者函數(shù),則用x作為值(結(jié)果)履行promise。 ;resolve(x) } }; if (self.status === "fulfilled") { //2.2.7 return (promise2 = new MyPromise((resolve, reject) => { //2.2.4 在執(zhí)行上下文堆棧僅包含平臺代碼之前,不能調(diào)用onFulfilled或onRejected。[3.1]。 //3.1 這里的“平臺代碼”是指引擎,環(huán)境和primise實現(xiàn)代碼。在實踐中,這個要求確保onFulfilled和onRejected異步執(zhí)行,在事件循環(huán)開始之后then被調(diào)用,和一個新的堆棧。這可以使用諸如setTimeout或setImmediate之類的“宏任務(wù)”機制,或者使用諸如MutationObserver或process.nextTick的“微任務(wù)”機制來實現(xiàn)。由于promise實現(xiàn)被認為是經(jīng)過深思熟慮的平臺代碼,因此它本身可能包含調(diào)用處理程序的任務(wù)調(diào)度隊列或或稱為“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í)行上下文堆棧僅包含平臺代碼之前,不能調(diào)用onFulfilled或onRejected。[3.1]。 //3.1 這里的“平臺代碼”是指引擎,環(huán)境和primise實現(xiàn)代碼。在實踐中,這個要求確保onFulfilled和onRejected異步執(zhí)行,在事件循環(huán)開始之后then被調(diào)用,和一個新的堆棧。這可以使用諸如setTimeout或setImmediate之類的“宏任務(wù)”機制,或者使用諸如MutationObserver或process.nextTick的“微任務(wù)”機制來實現(xiàn)。由于promise實現(xiàn)被認為是經(jīng)過深思熟慮的平臺代碼,因此它本身可能包含調(diào)用處理程序的任務(wù)調(diào)度隊列或或稱為“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方法,只要有一個失敗就失敗了。 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哪個先返回,就取哪個值,成功就取成功的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;
~~~ 如有不妥之處,歡迎大家留言指正,如覺得好請關(guān)注,點贊,轉(zhuǎn)發(fā)請注明出處,謝謝! ~~~
郵箱:gameness1212@163.com
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/93067.html
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個符合規(guī)范并可配合使用的寫一個符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個需求:在系統(tǒng)初始化時通過http獲取一個第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個接口,可通過...
摘要:的翻譯文檔由的維護很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
閱讀 1048·2021-11-22 15:33
閱讀 3357·2021-11-08 13:20
閱讀 1368·2021-09-22 10:55
閱讀 2053·2019-08-29 11:08
閱讀 771·2019-08-26 12:24
閱讀 3068·2019-08-23 17:15
閱讀 2225·2019-08-23 16:12
閱讀 1933·2019-08-23 16:09