什么是事件循环?Event Loop 宏任务/微任务
从Event Loop 到 async await
https://www.jianshu.com/p/8dccfa90ba59
运行在宿主环境中的Javascript引擎针对单线程,提供了一种机制来更高效地处理多个任务,这个机制不断地重复处理任务称为事件循环,事件循环具体地执行过程分为以下4步:
1.先执行主线程中的任务
2.当主线程空闲时,再从任务队列中读取任务,继续执行。
3.即使主线程阻塞了,任务队列还是会继续接收任务。
4.主线程不断地重复第2步操作。
http://www.ruanyifeng.com/blog/2013/10/event_loop.html
什么是 Event Loop?
https://github.com/forthealllight/blog/issues/5
https://cloud.tencent.com/developer/article/1476737
从promise、process.nextTick、setTimeout出发,谈谈Event Loop中的Job queue
setTimeout(function(){console.log(1)},0); new Promise(function(resolve,reject){ // promise 构造部分是同步执行的 console.log(2); resolve(); }).then(function(){console.log(3) }).then(function(){console.log(4)}); process.nextTick(function(){console.log(5)}); //nodejs里的定时器,执行顺序高于promise,promise高于setTimeout console.log(6); // 2,6,5,3,4,1
首先分析Job queue的执行顺序:
script(主程序代码)——>process.nextTick——>promise——>setTimeout
I) 主体部分: 定义promise的构造部分是同步的,
因此先输出2 ,主体部分再输出6(同步情况下,就是严格按照定义的先后顺序)
II)process.nextTick: 输出5
III)promise: 这里的promise部分,严格的说其实是promise.then部分,输出的是3,4
IV) setTimeout : 最后输出1
综合的执行顺序就是: 2——>6——>5——>3——>4——>1
Event Loop
任务队列中,在每一次事件循环中,macrotask(宏任务)只会提取一个执行,而microtask(微任务)会一直提取,直到microsoft队列为空为止。
也就是说如果某个microtask任务被推入到执行中,那么当主线程任务执行完成后,会循环调用该队列任务中的下一个任务来执行,直到该任务队列到最后一个任务为止。
//意思是主线程执行完成后,开始执行任务队列里的任务,直到队列任务全被执行然后结束
而事件循环每次只会入栈一个macrotask,主线程执行完成该任务(主线程中的同步任务的代码块)后又会检查microtasks队列并完成里面的所有任务后再执行macrotask的任务。
//在执行任务队列中的任务时,每次Event Loop只会入栈一个宏任务(主线程中的同步任务),执行完宏任务后检查队列中的微任务,执行完所有的微任务再来执行剩余的宏任务(定时器等等)
常见的宏任务和微任务:
macrotasks:js主代码块, setTimeout, setInterval, setImmediate, I/O, UI rendering(UI渲染)
microtasks: process.nextTick, Promise, MutationObserver
[宏任务:macro task]
- 定时器
- 事件绑定
- ajax
- 回调函数
- Node中fs可以进行异步的I/O操作
[微任务:micro task]
- Promise(async/await) => Promise并不是完全的同步,当在Excutor中执行resolve或者reject的时候,此时是异步操作,会先执行then/catch等,当主栈完成后,才会再去调用resolve/reject把存放的方法执行
- process.nextTick (node中实现的api,把当前任务放到主栈最后执行,当主栈执行完,先执行nextTick,再到等待队列中找)
- MutationObserver (创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用。)
https://zhuanlan.zhihu.com/p/257069622
console.log('1'); setTimeout(function() { console.log('2'); process.nextTick(function() { console.log('3'); }) new Promise(function(resolve) { console.log('4'); resolve(); }).then(function() { console.log('5') }) }) process.nextTick(function() { console.log('6'); }) new Promise(function(resolve) { console.log('7'); resolve(); }).then(function() { console.log('8') }) setTimeout(function() { console.log('9'); process.nextTick(function() { console.log('10'); }) new Promise(function(resolve) { console.log('11'); resolve(); }).then(function() { console.log('12') }) }) //1,7,6,8,2,4,3,5,9,11,10,12
总结一些前端常见的面试笔试题,来和大家分享鸭