在Javascript中,为什么在"已解决"的Promise上评估`then`方法会返回一个"待定"的Promise?

Han*_*Sun 2 javascript asynchronous promise ecmascript-6

以下是本机Javascript代码:

var first = Promise.resolve(1);
first.then((i)=>console.log(1))
Run Code Online (Sandbox Code Playgroud)

当我first在Chrome的控制台中检查时,它显示其状态为"已解决"

> first
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
Run Code Online (Sandbox Code Playgroud)

但是,当我first.then((i)=>console.log(1))在Chrome的控制台中检查时,它显示其状态为"待定"

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

这看起来让我感到困惑,因为我期望它first.then((i)=>console.log(1))具有状态,resolved因为then方法中的回调已经执行并完成.

有没有人有这个想法?

jfr*_*d00 5

Promise.resolve().then(fn) 返回一个尚未解决的新promise,但会在当前执行线程展开并完成后的下一个tick上解析.

因此,如果您立即检查是否已解决返回的承诺,则不会.但是,如果你等到下一个滴答,那么它将被解析,那时.then()处理函数将被触发.

为了解释,每个链式调用.then()返回一个链接到前一个的新promise.并且,根据Promise A +规范,所有.then()回调处理程序在堆栈展开后异步触发(技术上它表示类似"当只有平台代码在堆栈上时").

所以,.then()立即和同步运行.它存储您在promise对象中传递的回调,然后这些回调实际上是在将来的某个时间异步调用的.如果快速解决了promise,那么当前执行的线程完成时,将在下一个"tick"上调用完成回调.

这个堆栈在下一个滴答中展开和触发是为了使.then()处理程序始终异步触发,而不管请求解决的速度有多快.这允许在1ms或20分钟内立即解决承诺时以一致的方式写入调用代码.它们将在未来的某个时间异步解析,因此调用代码可以对它们进行相同的处理.唯一不同的是从现在起它们被解决或拒绝的时间.