上一次文章 异步操作和事件循环机制(Event Loop)中我们提到了 EventLoop ,而事件循环机制在 Node.js 与 浏览器中均存在,今天我们来看一下浏览器中的EventLoop
回顾:
- 属于微任务的事件有:
process.nextTick、promise、MutationObserver
- 属于宏任务的事件有
script、setTimeout、setInterval、setImmediate、I/O、UI rendering
-
EventLoop 队列
中存放的均是异步代码
浏览器中的EventLoop
-
代码一:
代码段1
问:以上代码的输出的结果是什么?
分析:
- 代码执行第一句,发现是 一个
setTimeout
,是一个异步任务,故将其放入EventLoop
中,又setTimeout
为宏任务,故将其放入宏任务队列中。
此时,宏任务队列:function(){console.log(4)}
- 执行第四句代码;执行第五句代码,
输出数字 1
;Promise
后的then
为异步代码,执行第六句代码,将.then(function(){console.log(5)})
放入微任务队列中
此时,微任务队列:function(){console.log(5)}
- 执行第七句代码,
输出数字5
- 执行第十一句代码,
输出数字 3
,至此,同步代码执行完毕,接下来进入EventLoop
阶段 - 首先执行的是微任务队列中的回调函数,即执行
function(){console.log(5)}
,输出数字5
,继续看微任务队列中是否还有回调函数,有的话就继续执行微队列中的回调函数,队列遵循先进先出的原则 - 执行完微任务,去执行宏任务中的回调函数,即执行
.then(function(){console.log(5)})
,输出数字4
。
至此,整段代码就全部执行结束,输出结果:1、2、3、5、4
-
代码二:
代码2
问:以上代码的输出的结果是什么?
分析:
-
async ..... await
为一个Promise
的语法糖,功能是使异步代码看起来像是以同步的方式执行的,await fn
后面的代码',要等fn
执行完后才能执行,即碰到await fn相关的代码
可改写成fn.then(后面的代码)
- 第一行到第八行均为函数声明,从第九行开始执行。进入
async1
,转到第一行开始执行,执行第二行输出数字1
,执行第三行代码,碰到await async2()
,将第三第四行代码改写成async2().then(()=>{console.log(2)})
,执行async2()
转到第六行,第七行输出数字3
,将后面的.then(()=>{console.log(2)})
放入微任务队列中。
此时,微任务队列:console.log(2)
- 开始执行第十行代码,第十一行
输出数字4
,将.then(function(){console.log(5)})
放入微任务队列中
此时,微任务队列:console.log(5)、console.log(2)
- 至此,同步代码执行完毕,接下来进入
EventLoop
阶段 - 执行 微任务,队列遵循先进先出原则,故先执行
console.log(2)
,输出数字2
;再执队列中的console.log(5)
,输出数字5
。 - 至此,整个代码块执行完毕,
输出结果:1、3、4、2、5
总结:浏览器中的EventLoop
,先执行微任务,将微任务队列中的回调函数执行完,再执行宏任务。队列遵循先进先出原则
下一篇文章写node.js
中的 EventLoop
网友评论