「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」。
什么是Event Loop? 众所周知,js是单线程的,从头执行到尾,遇到请求时间很长的情况时,程序就会被卡在这里,让用户很火大。 这时候呢,Event Loop就要发挥它的本事了。
Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。
在将eventloop之前,需要知道的是:
Javascript单线程任务被分为同步任务和异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。
异步任务之间是有执行优先级的区别的。不同的异步任务会被分为两类,微任务和宏任务
宏任务(MacroTask)需要多次事件循环才能执行完,setTimeout、setInterval、I/O、UI Rendering都属于宏任务
微任务(MicroTask)微任务是一次性执行完的。Process.nextTick(Node独有)、Promise属于微任务。
先执行的微任务,微任务执行完之后,在去执行队首的宏任务。
详解一下EventLoop的步骤(从浏览器方面):
【1】code从上而下执行,遇到异步任务将他们放在微任务队列/宏任务队列里
【2】code从上而下执行完,调用栈Stack清空
【3】从微任务队列取出队首回调任务,放在调用栈执行,执行完后,微任务队列长度-1
【4】继续取微任务队首的任务,执行,直到取完;注意,如果在执行microtask的过程中,又产生了microtask,那么会加入到队列的末尾,也会在这个周期被调用执行
【5】微任务队列执行完后,此时微任务队列为空,调用栈也为空
【6】取出宏队列队首的任务,放入Stack中执行,一次只从队列中取一个任务执行
【7】执行完毕后,调用栈Stack为空
【8】重复步骤3~7
举个🌰
console.log(1)
setTimeout(function(){
console.log(2)
}, 0) //放入宏队列
new Promise((resolve, reject)=> {
console.log(3); //这句是同步执行的
resolve(4);
}).then((data)=> {
console.log(data);
}) //放入微队列
setTimeout(function(){
console.log(5)
}, 0) //放入宏队列
console.log(6)
//1 3 6 4 2 5
ok,本篇就到此为止了,继续扫盲,拜拜~