Javascript 当存在密钥名为“的对象时,为何承诺处于挂起状态”;然后";

Javascript 当存在密钥名为“的对象时,为何承诺处于挂起状态”;然后";,javascript,promise,Javascript,Promise,JavaScript在下面的情况下工作得很奇怪 我看到了这个答案,并问了一个关于Javascript奇怪行为的问题: 我发现,如果我们将他的代码中的更改为任何其他键名,我们将得到完全不同的结果。 代码笔演示: 我试过Chrome和Firefox,他们都有这个问题。 我探索了那里的问题,找到了这个“bug”的一些基本规则 //这个将始终挂起 constPendingPromise=Promise.resolve(x=>x).then(r=>({then:y=>0})); pendingPromi

JavaScript在下面的情况下工作得很奇怪

我看到了这个答案,并问了一个关于Javascript奇怪行为的问题:

我发现,如果我们将他的代码中的
更改为任何其他键名,我们将得到完全不同的结果。
代码笔演示:

我试过Chrome和Firefox,他们都有这个问题。 我探索了那里的问题,找到了这个“bug”的一些基本规则

//这个将始终挂起
constPendingPromise=Promise.resolve(x=>x).then(r=>({then:y=>0}));
pendingPromise.then(r=>console.log(“promise resolved”);//“承诺已解决”将永远不会被记录
//谢谢@Jaromanda X的更正。更简单的版本是:
const pendingPromise1=Promise.resolve().then(()=>({then:y=>0}))

pendingPromise1.then(r=>console.log(“promise1已解决”);//“promise1 resolved”将永远不会被记录
它永远不会解析的原因是因为您的最终“then”永远不会调用resolve:

.then(r=>({then:y=>0}))
只返回一个非thenable
0

y
是一个解析回调。要使代码正常工作,请将
y
更改为
resolve
,然后调用它。或者,只需调用
y
。关键是,在解决问题之前,承诺仍然悬而未决

console.log(“启动奇怪的承诺”)
const pendingPromise=Promise.resolve(x=>x)。然后(r=>(
{然后:y=>“奇怪的承诺完成了!”}
));
pendingPromise.then(console.log)//永远不会发生
log(“启动黑客承诺”)
const hackedPromise=Promise.resolve(x=>x)。然后(r=>(
{then:resolve=>resolve(“黑客承诺完成!”)}
));

hackedPromise.then(console.log)//就像光速很快发生一样
我们都很熟悉这一点:在其中一个
。然后(回调)
,如果回调返回另一个承诺,比如
lastPromise
,整个承诺链(直到那时)将有效地“变成”
lastPromise

在内部,承诺链不会检查
lastPromise
是否是真正的承诺。它只检查是否实现了thenable接口(具有
.then()
方法)。如果确实如此,则进一步假设该方法也符合

承诺必须提供获取其当前或最终价值或原因的方法

promise的then方法接受两个参数:

承诺。然后(履行承诺,拒绝承诺)

现在,您将从回调返回一个对象,该对象具有
.then
方法,从而使其成为一个thenable。因此,承诺链将像对待同志一样对待这个对象,相信它是一个“承诺”,将其称为
。然后(oncompleted,onRejected)
(这实际上是
(resolve,reject)
对)

现在一个好的thenable知道如何处理
(oncompleted,onRejected)
。不幸的是,他们信任错了人。您的实现如下所示:

then = (onFulfilled) => 0
实际上,您从未调用
oncompleted(someValue)
来从挂起状态解析,因此,由于整个链现在“变成”
lastPromise
,但您的伪
lastPromise
无法解析/拒绝,整个链将永远处于挂起状态


这是一个悲惨的故事,盲目地相信任何一个能够成为承诺的人。

x=>x
r
完全不相关,所以第1点是错误的
pendingPromise=Promise.resolve().then(()=>({then:y=>0}))
行为相同通过阅读then方法应如何实现@Jaromanda X,您可能会对错误有所了解您是对的。谢谢你的更正。我已经更改了我的问题。为了避免混淆,它不必被称为
resolve
。。。它可以调用任何东西,因为它是传递给then的
onresolved
回调(两个回调之一)。。。因此,原始代码只需要是
{then:y=>y(0)}