事件循环机制
每一个JavaScript程序都拥有唯一的事件循环,大多数代码的执行顺序是可以根据函数调用栈的规则执行的,而setTimeout/setInterval或者不同的事件绑定(click、mousedown等)中的代码,则通过队列来执行。
setTimeout为任务源,由它们将不同的任务分发到不同的任务队列中,每一个任务源都有对应的任务队列。
任务队列分为宏任务(macro-task)与微任务(micro-task):
- macro-task:script(整体代码)、setTimeout/setInterval、I/O、UI rendering等。
- micro-task:Promise。
node.js中包括更多的任务队列
js执行机制是 Event Loop 事件循环,先顺序执行同步事件即宏任务,碰到异步事件将其分类丢入宏任务 Event Queue 和微任务 Event Queue 中,等宏任务执行结束后顺序执行完微任务 Event Queue 中任务,第一次循环结束;顺序执行宏任务 Event Queue 中任务,如此往复。
setTimeout(function(){
console.log("timeout");
})
new Promise(function(resolve){
console.log("promise1");
for(var i=0;i<000;i++){
i==99 && resolve();
}
console.log("promise2");
}).then(function(){
console.log("then1");
})
console.log("global1");
- 第一轮循环,setTimeout作为一个宏任务源,将任务分发到对应的队列中;
- Promise构造函数的第一个参数是在new创建实例的时候执行,因此不会进入任何队列,而是在当前任务中直接执行;
- 后续的.then则会被分发到micro-task的Promise队列中;globel输出,第一轮循环的宏任务执行完毕;
- 开始执行所有可执行的微任务,Promise队列中的then1输出,所有的micro-tast执行完毕,第一轮循环结束;
- 开始第二轮循环,执行setTimeout队列中的timeout1任务,所有任务执行完毕。