我在学习诺言,我发现了这段代码
async function main() {
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log("hello");
resolve();
}, 1000);
});
console.log("world");
}
main();
它产生的输出是“hello world”。
我无法理解的是,为什么内部控制台日志“console.log(“world”)”正在等待承诺的解决。
如果我在这里遗漏了什么,如果我能得到一些帮助来理解这一点,或者是一些文档的链接,以供进一步阅读,那将是一件好事。
提前谢谢。
4条答案
按热度按时间xqk2d5yq1#
我错过了什么吗
直截了当地说是的,你错过了第二行的第一个单词。了解那里发生了什么的关键是
await
。你正在创造一个承诺
这个承诺将启动一个异步操作,该操作可能在将来某个地方结束(在这个特定情况下为1秒后)。
您可能认为此操作应该在
console.log("world");
之后执行,如果promise之前没有await
,则可能会发生这种情况。但我们确实有这个
await
,所以我们经常对程序说“嘿,我想等这个动作结束,然后再继续”。这就是为什么我们在
world
之前看到打印的hello
。pb3skfrl2#
等待表达式通过暂停执行直到返回的promise被满足或拒绝,使promise返回函数表现得好像是同步的。
来源
让我们一步一步地将其分解,不要把事情过于复杂。这是
main()
函数内部发生的情况:1.第一行按预期执行,但函数中的关键字
await
会停止进程(必须首先满足或拒绝promise)1.在promise中有
setTimout()
,另一个异步函数,但这一个没有等待;setTimeout()是一个异步函数,这意味着计时器函数不会暂停函数堆栈中其他函数的执行。换句话说,在函数堆栈中的下一个函数激发之前,不能使用setTimeout()创建“暂停”。来源
然而,执行似乎暂停了,但这并不是因为
setTimeout()
函数本身。这是因为承诺有待解决。我们什么时候解决?1秒钟后。1.
setTimeout()
内的回调按预期执行:首先打印console.log('hello')
,然后用resolve()
解析promise。1.随着承诺得到解决,
console.log('world')
的进展最终得以继续。因此,我们最终
您可以尝试将
resolve()
移动到setTimeout()
之外,并观察promise是如何立即解析的,以及打印的消息是如何反转的(因为,正如我前面所说,setTimout()
本身不会暂停promise的执行)。总结一下:
我无法理解的是,为什么内部控制台日志>“console.log(“world”)”正在等待承诺的解决。
console.log("world")
不是在等待承诺,而是在等待setTimeout()
内部的延迟。就像诺言等待解决一样:它发生在console.log("world")
之后。neskvpey3#
了解JS事件循环wait with promise关键字wait for resolve or reject Fireship有一个很好的解释https://www.youtube.com/watch?v=vn3tm0quoqE&t=587s&ab_channel=Fireship
iih3973s4#
因为这就是承诺的工作方式。它们旨在始终返回明确的结果。阅读https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise了解更多信息。