我对如何将以下测试代码放入 JS 事件循环中感到困惑。
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1)
}, 100)
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(2)
}, 0)
});
p1.then((value)=>{console.log(value)})
p2.then((value)=>{console.log(value)})
根据我的理解,setTimeout函数不是会被同步调用,然后在两个.then事件之后添加到微任务队列中吗?但这是否意味着在当前迭代结束时,两个微任务甚至在解析函数运行之前运行?或者当调用resolve函数时,与该promise相关的所有微任务都会在当前迭代结束时调用?
我认为最好有人可以向我逐步解释如何将代码添加到事件循环中然后运行。
setTimeout函数不是会被同步调用吗
是的,
setTimeout
将被同步调用。
然后就在两个 .then 事件之后添加到微任务队列中?
不。调用
setTimeout
会在任务队列中安排一个任务,以在计时器到期时执行传递给 setTimeout
调用的回调。即使您传递零作为延迟,回调也会被异步调用。
但这是否意味着在当前迭代结束时,两个微任务会在解析函数运行之前运行?
两个 Promise 都将异步解决。代码的同步执行结束后,由于代码中的两个
setTimeout
调用,even 循环可以开始处理预定的回调。
只有当一个promise被解决并且它们是为该promise注册的履行处理程序时,作业才会在微任务队列中排队以执行履行处理程序。
以下步骤描述了您的代码执行:
这两个 Promise 都是由于
Promise
构造函数调用而创建的。传递给 Promise
构造函数的函数作为 Promise 创建过程的一部分被同步调用。因此,两个 setTimeout
回调计划在各自的计时器到期后执行。
两个 Promise 相继创建后,分别在 Promise
then
和 p1
上调用 p2
方法。这会注册两个承诺的履行处理程序。
至此,代码的同步执行结束了。现在,事件循环将处理任务队列中安排的任何回调。一旦各自的计时器到期,两个
setTimeout
回调都会被放入任务队列中。
一旦执行了两个
setTimeout
回调,两个 Promise 就会相继得到解决。一旦任何承诺得到解决,为了执行其履行处理程序,作业就会被排入微任务队列中。总共将有两个作业在微任务队列中一个接一个地排队,以执行两个 Promise 的履行处理程序。