我最近在Stack Overflow上遇到了this question个问题,询问THEN方法在JavaScript中到底是如何工作的.回复人Trin Cot发表了以下 comments :
主机将判断哪些作业(job)队列具有条目,优先考虑具有高优先级的作业(job)队列.Promise作业(job)队列具有非常高的优先级,通常高于处理用户交互或其他外部事件的事件队列.因此,在上述步骤4中放置在队列中的作业(job)将从Promise作业(job)队列中取出.该作业(job)将按顺序调用已注册为myPromise对象上的回调函数的回调函数(如在步骤7中注册的回调函数).
如果我正确理解了他的解释,那么每当调用Resolve函数时,JavaScript都会在作业(job)队列中调度一个微任务(或作业(job)),当调用堆栈为空时,该作业(job)队列将执行传递给THEN的所有回调,包括链接.例如:
Promise.resolve("Hi")
.then(() => {
console.log("Hi");
})
.then(() => {
console.log("World");
});
在这种情况下,promise 被立即解析,这意味着微任务将被立即调度.当THEN回调完成执行时,JS引擎将判断队列中的任何微任务.因为promise 是立即解析的,所以它将执行微任务,而微任务又执行传递给THEN方法的所有处理程序.因此,代码将输出"Hi"和"World".
但是,为什么这段代码输出的是"1 3 2 4"而不是"1 2 3 4"?
const p1 = Promise.resolve();
const p2 = Promise.resolve();
p1.then(() => {
console.log(1);
}).then(() => {
console.log(2);
});
p2.then(() => {
console.log(3);
}).then(() => {
console.log(4);
});
我认为代码应该输出"%1 2%3%4",而不是"%1%3%2%4".这是因为,当p1和p2解析时,两个微任务被排队.当随后的回调完成执行时,它们会将这些回调添加到其内部列表中.一旦调用堆栈为空,JS引擎就从队列中 Select 最旧的任务并执行它.该任务应该执行传递给该特定Promise实例的所有处理程序.然而,这似乎并没有像预期的那样发生.谁能给我解释一下这种行为背后的原因?
感谢您抽出时间,祝您度过愉快的一天!