在以下情况下,JavaScript工作异常。
我看到了这个答案,并得到了有关Javascript怪异行为的问题:https://stackoverflow.com/a/50173415/1614973
我发现,如果将他的代码中的then
更改为任何其他键名,我们将得到完全不同的结果。
CodePen演示:his,changed
我尝试了Chrome和Firefox,但它们都存在此问题。 我在那里探索了问题,并找到了这个“错误”的一些基本规则。
// This one will always pending
const pendingPromise = Promise.resolve(x=>x).then(r => ({ then: y => 0 }));
pendingPromise.then(r => console.log("promise resolved")); // "promise resolved" will never logged
// Thanks @Jaromanda X's correction. a simpler version is:
const pendingPromise1 = Promise.resolve().then(() => ({then: y => 0}))
pendingPromise1.then(r => console.log("promise1 resolved")); // "promise1 resolved" will never logged
pendingPromise
永远待定。据我所知,有三件事可以切换此错误:
.then
中,必须返回键名称为“ then”的Object。then
的值必须是一个函数。我想知道为什么会这样。
答案 0 :(得分:1)
它永远无法解决的原因是,您最后的“ then”永远不会解决:
.then(r=>({then: y => 0}))
仅返回不可修改的0
。
y
是一个解析回调。要使代码正常工作,请将y
更改为resolve
,然后调用它。或者,只需致电y
。关键是,在调用解决方案之前,承诺仍然处于待处理状态。
console.log("Starting Strange Promise")
const pendingPromise = Promise.resolve(x=>x).then(r=>(
{then: y => "Strange Promise Done!"}
));
pendingPromise.then(console.log) // never happens
console.log("Starting Hacked Promise")
const hackedPromise = Promise.resolve(x=>x).then(r=>(
{then: resolve => resolve("Hacked Promise Done!")}
));
hackedPromise.then(console.log) // happens, like, speed of light quickly
答案 1 :(得分:1)
我们都很熟悉:在.then(callback)
之一中,如果回调函数返回另一个承诺,例如lastPromise
,则整个承诺链(到那时为止)将有效地“成为” { {1}}。
在内部,promise链根本不会检查lastPromise
事物是否是真正的Promise。它仅检查其是否实现了 thenable接口(具有lastPromise
方法)。如果是,则进一步假设该方法也符合spec。
承诺必须提供then方法来访问其当前或最终值或原因。
promise的then方法接受两个参数:
.then()
现在,您从回调函数中返回一个具有promise.then(onFulfilled, onRejected)
方法的对象,这使该对象成为可能的。因此,promise链会将这个对象视为同志,认为它是一个“承诺”,将其称为.then
(实际上是.then(onFulfilled, onRejected)
对)。
现在,一个善良的牧师知道与(resolve, reject)
相关的事情。不幸的是,他们信任错误的人。您的实现如下:
(onFulfilled, onRejected)
您从未真正调用then = (onFulfilled) => 0
来从挂起状态解决,所以既然整个链现在都“成为” onFulfilled(someValue)
,但是您的假lastPromise
无法解决/拒绝,整个链只是停留在待命状态。
那是一个盲目地信任任何可以成为诺言的悲惨故事。