promise中的异步函数(如计时器)在Javascript中如何处理?



我们知道承诺是微任务,它们被添加到微任务队列中,事件侦听器/计时器是任务,因此它们被添加到任务队列中。但是,如果事件侦听器/计时器位于 promise 函数内部(该函数在创建 promise to promise 构造函数时传递(,那么它们呢?它们被添加到哪个队列中?

console.log("script start");
var promise = new Promise(function (resolve, reject) {
	setTimeout(function () {
		console.log("setTimeout2");
		resolve();
	}, 0);
});
promise.then(function () {
	console.log("promise2");
});
setTimeout(function () {
	console.log("setTimeout");
}, 0);
console.log("script end");

这里的"脚本启动"是主任务的一部分,因此它被执行/打印。

然后将 promise 的回调函数处理给浏览器,处理程序将其添加到微任务队列中。

then(( 将回调传递给浏览器的处理程序,它将在解决主承诺后执行。

承诺之外的 setTimeout 将添加到任务队列中。

打印"脚本结束"。

现在微任务队列上有一个微任务,任务队列上有一个任务。

因此,微任务将首先执行,因为它们的优先级高于任务。

但是在任务内部,有一个计时器。

我们知道计时器已添加到任务队列中。但在这里我认为计时器被添加到微任务队列中。因为如果它被添加到任务队列中,那么"setTimeout2"将在稍后打印,因为在任务队列上已经有一个打印"setTimeout"的任务。 那么那里到底发生了什么?

"在承诺中"没有什么特别之处。放在微任务队列中的唯一函数是传递给then的回调。

以下是实际发生的情况:

  1. 执行script start日志
  2. 创建承诺并调用其执行器回调。执行器回调调用setTimeout,这会调度计时器。
  3. 承诺被分配给promise变量
  4. 调用then()方法并将履行回调附加到承诺
  5. 调用第二个setTimeout并计划第二个计时器
  6. 执行script end日志

这一切都在一个任务执行中同步发生。一段时间后,计时器触发并(只有这样!(将其(宏(任务添加到计时器事件队列中。浏览器处理第一个:

  1. 执行setTimeout2日志
  2. 执行resolve()函数,该函数履行承诺并添加作业以运行履行回调到微任务队列

完成此宏任务后,将处理微任务队列中的任务:

  1. 执行promise2日志

由于微任务队列已经是空的,因此可以处理下一个宏任务:

  1. 执行setTimeout日志

最新更新