简体   繁体   English

在Javascript中,为什么对“已解决”的Promise评估`then'方法会返回“待处理”的Promise?

[英]In Javascript, why evaluating a `then` method on a “resolved” Promise returns a “pending” Promise?

Following is the native Javascript code: 以下是本机Javascript代码:

var first = Promise.resolve(1);
first.then((i)=>console.log(1))

When I inspect first in the console of Chrome, it shows its status is "resolved" 当我first在Chrome控制台中检查时,它显示其状态为“已解决”

> first
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}

However, when I inspect first.then((i)=>console.log(1)) in the console of Chrome, it shows that its status is "pending" 但是,当我在Chrome控制台中先检查first.then((i)=>console.log(1))时,它表明其状态为“待处理”

> first.then((i)=>console.log(1))
1
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}

This looks confusing to me because I expected the first.then((i)=>console.log(1)) has the status of resolved as the callback within the then method has already been executed and finished. 这让我感到困惑,因为我期望first.then((i)=>console.log(1))的状态为已resolved因为then方法中的回调已经执行并完成。

Does anyone have ideas about this? 有人对此有想法吗?

Promise.resolve().then(fn) returns a new promise that is not yet resolved, but will be resolved on the next tick after the current thread of execution unwinds and finishes. Promise.resolve().then(fn)返回一个尚未解决的新承诺,但将在当前执行线程结束并完成后的下一个滴答中解决。

Thus, if you immediately check to see if the returned promise is yet resolved, it will not be. 因此,如果您立即检查返回的诺言是否已解决,则不会。 But, if you wait until the next tick, it will then be resolved and the .then() handler function will be fired at that time. 但是,如果您等到下一个刻度线,它将被解析,并且届时将触发.then()处理函数。

To explain, each chained call to .then() returns a new promise that is chained to the prior one. 解释一下,对.then()每个链式调用都会返回一个新的诺言,该诺言链接到前一个诺言。 And, per the Promise A+ specification, all .then() callback handlers are fired asynchronously after the stack has unwound (technically it says something like "when only platform code is on the stack"). 并且,根据Promise A +规范,所有.then()回调处理程序在堆栈解开后都将异步触发(从技术上讲,它表示“仅当平台代码在堆栈中时”)。

So, .then() runs immediately and synchronously. 因此, .then()立即并同步运行。 It stores the callback(s) you pass it in the promise object and then those callbacks are actually called asynchronously some time in the future. 它将您传递给它的回调存储在promise对象中,然后在将来的某个时间实际上异步调用这些回调。 If the promise is resolved quickly, then the fulfill callback will be called on the next "tick" when the current thread of execution has finished. 如果Promise很快得到解决,那么当当前执行线程完成时,将在下一个“滴答”中调用完成回调。

This stack unwinding and firing on the next tick is to make it so that .then() handlers are consistently firing asynchronously, not matter how quickly the promise is resolved. 堆栈的展开和下一次触发是为了使.then()处理程序始终一致地异步触发,而不管承诺被解决的速度如何。 This allows the calling code to be written in one consistent manner when the promise is resolved immediately, in 1ms or in 20 minutes. 这样,当立即解决承诺时(在1ms或20分钟内),可以以一种一致的方式编写调用代码。 They will all get resolved asynchronously some time in the future and thus the calling code can treat them all the same. 它们将在将来的某个时间被异步解析,因此调用代码可以将它们全部相同。 The only thing that will be different is how long from now they are resolved or rejected. 唯一不同的是,从现在起它们将被解决或拒绝多长时间。

For promises that confirm to Promise/A+ spec , for a then call of the form 对于确认符合Promise / A +规范的承诺then致电该表格

promise.then(onFulfilled, onRejected)

there is a condition that 有一个条件是

onFulfilled or onRejected must not be called until the execution context stack contains only platform code. 在执行上下文堆栈仅包含平台代码之前,不得调用onFulfilled或onRejected。

So, assuming Chrome adheres to this spec for its promises, and only sets the (internal?) Promise status to resolved once the callbacks have been called, calling 因此,假设Chrome遵守此规范以实现其承诺,并且仅在调用了回调后才将(internal?)Promise状态设置为“ resolved ”,

Promise.resolve(1).then(onFulfilled, onRejected);

will always show an unresolved promise since the stack has not yet cleared and the callbacks not yet called. 由于堆栈尚未清除且回调尚未调用,因此将始终显示未解决的Promise。 However, 然而,

var derived = Promise.resolve(1).then(onFulfilled, onRejected);

And then later, in the inspector calling 然后,在检查器中调用

derived;

will show a resolved promise since the stack has cleared and the callbacks called. 由于已清除堆栈并调用了回调,因此将显示已解决的Promise。 The call to 致电

Promise.resolve(1);

is not subject to the constraint on having to wait for the stack to clear, and so returns an immediately resolved promise. 不必等待必须清除堆栈的约束,因此返回立即解决的promise。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM