分支承诺的执行顺序



JavaScript Promise分支的执行顺序有规范吗?

请考虑以下代码:


// Create a promise that will be resolved when we call the function `r`
let r;
const promise = new Promise((resolve, reject) => {
r = resolve; // Store the resolver in `r`, so we can call it later.
});
// When `promise` resolves, print "I am the first branch".
promise.then(() => console.log("I am the first branch"));
// When `promise` resolves, also print "I am the second branch".
promise.then(() => console.log("I am the second branch"));

// Resolve `promise`
r();

承诺promise分为两个分支。

根据我的测试,第一个分支在第二个分支之前执行。

I am the first branch
I am the second branch

我的问题: 这是由 JavaScript 规范保证的,还是我依赖于未定义的行为?

注意: 当然,我可以把承诺链起来。喜欢这个:

promise.then(() => console.log("I am the first branch")).then(() => console.log("I am the second branch"));

但如果可能的话,我更愿意对它们进行分支。

在这种情况下(->在同一承诺上多次调用.then())...

const p = new Promise((resolve, reject) => { setTimeout(resolve, 1000) });
p.then(() => console.log("first"));
p.then(() => console.log("second"));

。顺序是有保证的,因为.then()就像一个带有数组的.push()。规范中的相关路径为:

第 5 步(Promise.prototype.then)+ 步骤 9.a (PerformPromiseThen

)

27.2.5.4Promise.prototype.then ( onFulfilled, onRejected )

当使用参数调用 then 方法时onFulfilledonRejected,将采取以下步骤:

1. Let promise be the this value.
2. If IsPromise(promise) is false, throw a TypeError exception.
3. Let C be ? SpeciesConstructor(promise, %Promise%).
4. Let resultCapability be ? NewPromiseCapability(C).
5. Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).

然后

27.2.5.4.1PerformPromiseThen ( promise, onFulfilled, onRejected [ , resultCapability ] )

抽象操作PerformPromiseThen接受参数承诺,onFulfilledonRejected和可选参数resultCapability(aPromiseCapability记录)。它执行"then"操作的承诺 使用onFulfilledonRejected作为其结算操作。如果 传递resultCapability,则通过更新来存储结果resultCapability的承诺。如果未通过,则PerformPromiseThen由规范内部调用 结果无关紧要的操作。它执行以下操作 调用时的步骤:

1. Assert: IsPromise(promise) is true.
2. If resultCapability is not present, then
a. Set resultCapability to undefined.
3. If IsCallable(onFulfilled) is false, then
a. Let onFulfilledJobCallback be empty.
4. Else,
a. Let onFulfilledJobCallback be HostMakeJobCallback(onFulfilled).
5. If IsCallable(onRejected) is false, then
a. Let onRejectedJobCallback be empty.
6. Else,
a. Let onRejectedJobCallback be HostMakeJobCallback(onRejected).
7. Let fulfillReaction be the PromiseReaction { [[Capability]]: resultCapability, [[Type]]: Fulfill, [[Handler]]: onFulfilledJobCallback }.
8. Let rejectReaction be the PromiseReaction { [[Capability]]: resultCapability, [[Type]]: Reject, [[Handler]]: onRejectedJobCallback }.
9. If promise.[[PromiseState]] is pending, then
a. Append fulfillReaction as the last element of the List that is promise.[[PromiseFulfillReactions]].
b. Append rejectReaction as the last element of the List that is promise.[[PromiseRejectReactions]].
10. Else if promise.[[PromiseState]] is fulfilled, then
a. Let value be promise.[[PromiseResult]].
b. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
11. Else,
a. Assert: The value of promise.[[PromiseState]] is rejected.
b. Let reason be promise.[[PromiseResult]].
c. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "handle").
d. Let rejectJob be NewPromiseReactionJob(rejectReaction, reason).
e. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
12. Set promise.[[PromiseIsHandled]] to true.
13. If resultCapability is undefined, then
a. Return undefined.
14. Else,
a. Return resultCapability.[[Promise]].

最新更新