调用栈(call stack)、消息队列(Message Queue)、微任务队列(Microtask Queue)
宏任务:script全部代码、setTimeout、setInterval、setImmediate、I/O、UI Rendering。
微任务:Process.nextTick(Node 独有)、Promise 等。
JS代码在浏览器中运行时单线程的,event loop 会一行一行的执行代码
遇到函数就会把函数压入调用栈中执行函数里的代码 代码执行完毕 弹出
遇到宏任务 就把宏任务压入消息队列
遇到微任务 就把微任务压入微任务队列
当主线程中的代码全部执行完毕 调用栈清空后,就会开始只执行消息队列里的宏任务;但是每一次执行消息队列里的宏任务之前,就必须先查看一下微任务队列里的微任务,每一次执行宏任务前必须把微任务队列里的微任务执行完毕。
let p = new Promise(function(resolve){
console.log(3)
resolve()
})
function fn1(){
console.log(5)
setTimmout(function(){
console.log(4)
},0)
}
function fn2(){
p.then(funtion(){
console.log(1)
})
console.log(6)
fn1()
console.log(7)
}
fn2();
调用栈 消息队列
| | -------------------------
| | consolo.log(4)
| | -------------------------
------------------------
微任务队列
-------------------------
consolo.log(1)
-------------------------
//输出 3 6 5 7 1 4
JS线程会先把 fn2 压入调用栈 执行函数代码;p.then()执行 把log(3)压入调用栈然后执行 输出 3 弹出;把log(1)压入微任务队列;把log(6)压入调用栈 输出6 弹出;fn1 压入调用栈, log(5)被踏入执行 输出 5 弹出;把settimeout log(4) 压入消息队列;fn1 执行完毕 弹出,继续执行fn2 代码 ;log(7)压入调用栈 输出7 弹出;fn2 执行完毕弹出 ,调用栈空! 执行消息队列,每一次执行消息队列前,检查微任务队列是否为空,不为空则执行微任务队列,log(1) 输出1 弹出; 微任务队列为空执行宏任务队列 log(4) 输出4 弹出;宏任务队列为空,代码执行完毕。