JavaScript 关于事件循环机制的刨析
什么是事件循环机制
JavaScript 引擎采用的是单线程执行模式,只有一个调用堆栈,每一次执行上下文都会从调用堆栈依次出栈,为了解决程序中出现的异步执行问题,JavaScript 引入了事件循环机制。
事件循环机制是指,当 JavaScript 引擎执行完调用堆栈中所有任务后,会去检查任务队列中是否还有任务未执行,如果有则将队列中的任务出队执行,直到队列为空。
事件循环机制的执行顺序
事件循环机制中的任务分为 MacroTask 和 MicroTask 两种,执行顺序如下:
-
首先执行所有的 MacroTask 任务,包括 setTimeout 和 setInterval 函数产生的 MacroTask 任务。
-
在执行完所有 MacroTask 任务后,依次执行 MicroTask 任务队列中的所有任务,包括 Promise.then() 或 async/await 函数中产生的 MicroTask 任务。
-
重复以上两个步骤,直到任务队列为空。
示例说明
示例1
setTimeout(() => {
console.log('setTimeout 1');
}, 0);
Promise.resolve().then(() => {
console.log('resolve 1');
}).then(() => {
console.log('resolve 2');
});
setTimeout(() => {
console.log('setTimeout 2');
}, 0);
以上代码中,两个 setTimeout 函数产生的 MacroTask 任务会比 Promise.then() 函数产生的 MicroTask 任务先执行。因此,先输出 'setTimeout 1' 和 'setTimeout 2' ,后输出 'resolve 1' 和 'resolve 2'。
示例2
console.log('script start');
async function async1() {
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2 end');
}
async1();
setTimeout(() => {
console.log('setTimeout');
}, 0);
new Promise(resolve => {
console.log('Promise');
resolve();
}).then(() => {
console.log('Promise then');
});
console.log('script end');
以上代码中,先执行的是同步代码块,因此先输出 'script start' 和 'script end'。接着执行 async1 函数,由于 async2 函数是异步操作,会被放入 MicroTask 队列中,接着执行 setTimeout 和 Promise 函数,产生了两个 MacroTask 任务和一个 MicroTask 任务,执行顺序如下:
-
输出 'async2 end'。
-
async2 函数执行完毕后,async1 函数接着执行,输出 'async1 end'。
-
执行 MicroTask 队列中的 Promise.then() 函数,输出 'Promise then'。
-
执行 MacroTask 队列中的 setTimeout 函数,输出 'setTimeout'。
因此输出的结果为:
script start
async2 end
Promise
async1 end
Promise then
setTimeout
script end
以上是 JavaScript 关于事件循环机制的一个初步刨析。深入了解事件循环机制是非常有必要的,能帮助我们更好地理解和应用 JavaScript。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript 关于事件循环机制的刨析 - Python技术站