【问题标题】:How async functions(such as timers) inside promise are handled in Javascript?Javascript中如何处理promise中的异步函数(例如计时器)?
【发布时间】:2020-10-09 00:12:50
【问题描述】:

我们知道 Promise 是微任务,它们被添加到微任务队列中,而事件监听器/定时器是任务,因此它们被添加到任务队列中。但是,如果事件侦听器/计时器位于 Promise 函数中(在创建 Promise 时将其传递给 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的回调函数被处理到浏览器,handler把这个加入到微任务队列中。

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

promise 之外的 setTimeout 被添加到任务队列中。

“脚本结束”被打印出来。

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

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

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

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

【问题讨论】:

    标签: asynchronous promise


    【解决方案1】:

    “承诺”并没有什么特别之处。放入微任务队列的唯一函数是传入then 的回调函数。

    这是实际发生的事情:

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

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

    1. setTimeout2 日志被执行
    2. resolve() 函数被执行,该函数实现了 Promise 并将作业添加到微任务队列中以运行实现回调

    这个宏任务完成后,处理微任务队列中的任务:

    1. promise2 日志被执行

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

    1. setTimeout 日志被执行

    【讨论】:

      猜你喜欢
      • 2012-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 1970-01-01
      • 2023-01-16
      相关资源
      最近更新 更多