审核中~
溜忙之道
首页
溜忙手册
offer之道
项目Git
写文章
登录
·
注册
登录
没有账号,去注册
注册
已有账号,去登录
博客
浅谈浏览器 eventloop 与 Nodejs eventloop 的不同点
南易_站长
阅读量:15150
关注
浅谈浏览器 eventloop 与 Nodejs eventloop 的不同点
# 浅谈浏览器 eventloop 与 Nodejs eventloop 的不同点 ### 示例代码 浏览器和 Node 都有事件轮询的机制,虽然都属于 JavaScript,但二者的内部机制完全不同。 以下面这段代码为例 ```jsx setTimeout(()=>{ console.log('timer1') Promise.resolve().then(function() { console.log('promise1') }) }, 0) setTimeout(()=>{ console.log('timer2') Promise.resolve().then(function() { console.log('promise2') }) }, 0) Promise.resolve().then(function() { console.log('promise3') }) ``` 在浏览器中它的输出顺序是 promise3=>timer1=>promise1=>timer2=>promise2。 而在 Node 中它的输出顺序变为了 promise3=>timer1=>timer2=>promise1=>promise2。 ### 宏任务的分类与微任务何时执行 接下来我们先说明两个概念——宏任务与微任务: * macrotask:包含执行整体的js代码,事件回调,XHR回调,定时器(setTimeout/setInterval/setImmediate),IO操作,UI render * microtask:更新应用程序状态的任务,包括promise回调,MutationObserver,process.nextTick,Object.observe 浏览器与 Node 事件轮询的不同点就在于宏任务是否归类与微任务何时执行。 在浏览器中,**宏任务会按照事件队列中的顺序依次执行**,宏任务有可能产生微任务,**微任务队列会在当前宏任务执行结束后立即执行**。 在 Node 中,将宏任务分为六种,如果加上整体的 js 代码一共有七种。具体如下: ![null](https://upload-images.jianshu.io/upload_images/5816904-70156ea9e189339f.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp) 图片.png > timers 阶段:这个阶段执行timer(setTimeout、setInterval)的回调 > I/O callbacks 阶段:执行一些系统调用错误,比如网络通信的错误回调 > idle, prepare 阶段:仅node内部使用 > poll 阶段:获取新的I/O事件, 适当的条件下node将阻塞在这里 > check 阶段:执行 setImmediate() 的回调 > close callbacks 阶段:执行 socket 的 close 事件回调 在 Node 中 js 整体代码执行结束后,会将相应的宏任务放到相应的阶段,然后**从 timer 阶段开始不断循环执行**。每个阶段产生的宏任务会放到其应该属于的阶段,产生的**微任务队列会在当前阶段执行结束后立即执行**。 ### 代码分析 下面我们来逐步分析两个环境的输出为什么不同。 首先可以确定一点,整体 js 代码会先执行,并且从上到下同步执行一遍。在执行的过程中,会碰到异步的代码,即 Promise.then 和 setTimeout ,这两个函数内部的回调函数都不会在这个同步过程中执行。 整体的 js 代码执行后产生了一个微任务 (promise3) 和两个宏任务(timer1、timer2)。 在浏览器中会先执行 promise3 再执行 timer1,执行 timer1 后产生的 promise1 会紧接着 timer1 执行,最后是 timer2 与 promise2。 在 Node 中同样会先执行 promise3 再执行 timer1,但是 timer1 之后会接着执行 timer2,因为这是在 timer 阶段。在 timer1 与 timer2 中产生的两个微任务会在 timer 阶段结束后依次执行。 1人点赞 [前端集](https://www.jianshu.com/nb/13178222)
评论
表情
发送
0
评论