浏览器和Node中eventloop的区别(js执行机制)
一、浏览器端的eventloop
1)1个函数执行栈,1个微任务队列,1个时间队列
2)宏任务与微任务
- 宏任务: macrotask 也叫tasks,异步回调会进入tasks,其包含:
- setTimeout
- setInterval
- setImmediate(Node)
- requestAnimationFrame (浏览器)
- I/O
- UI rendering
- 微任务: microtask, 也叫jobs,另一些异步任务microtask,其包含:
- process.nextTick(Node)
- promise.then()
- Object.observe
- Mutation.observer
执行顺序:执行栈 > 微任务 > 宏任务
二、 NodeJs中的eventloop
执行机制:
- times(计时期)
- I/O callbacks处理流、网络、tcp错误callback
- idle、prepare node内部使用
- poll轮询,执行poll中的I/O队列,检查定时器是否到时
- check(检查)存放setImmediate回调
- close callbacks关闭回调 socket.on('close')
执行过程:
- 执行js中的同步代码
- 执行microtask微任务,先执行NextTickQueue中的所有任务,在执行Other Microtask Queue中的所有任务。
- 开始执行macrotask宏任务,共6个阶段,从第1个阶段开始,执行相应的每个阶段macrotask中的所有任务,注意:这里是所有每个阶段宏任务队列的所有任务,在浏览器中的eventloop只取宏任务中的第一个任务出来执行,每一个阶段的macrotask任务执行完毕后,开始执行微任务,也就是步骤2
- Times queue -> 步骤2 -> I/O queue -> 步骤2 -> check queue -> 步骤2 -> close callback queue -> 步骤2 -> timers queue
- 这就是node的eventloop的简化版
三、浏览器和Node中的eventloop的区别
- 实现机制不同
- nodejs可以理解成4个宏任务和2个微任务队列,但执行宏任务时,有6个步骤
- Nodejs中,先执行全局的js代码,执行完同步代码调用栈,清空后,先从微任务队列NextTick queue中依次取出所有的任务,放入调用栈执行;再从微任务队列中的other microtask queue中依次取出所有任务放入调用栈执行。然后开始宏任务的6个阶段,每个阶段都将该宏任务队列中的所有任务都取出来执行,每个宏任务阶段执行完毕后,开始执行微任务,在开始执行下一阶段的宏任务,以此构建事件循环。
- Microtask包括:setTimeout\setInterval\setImmediate\requestAnimation\I/O\UI rendering
- Microtask包括:process.nextTick(Node)\promise.then()\Object.observe\Mutation.observer
注意:new promise()构造函数里面的是同步代码,非微任务