学习笔记之事件循环-Event loop

前言

本文仅以记录浏览器环境的event loop 和 node环境中的event loop的了解过程,若是错误,欢迎指正

浏览器环境

Event Loop是指在js执行环境中存在主执行线程和任务队列(Task Queue),其中全部同步任务都在主执行线程中造成一个执行栈,全部异步任务都会放到任务队列中

具体执行过程:
1. 主线程执行同步任务, 在主线程执行的过程当中,不断行程堆栈并执行出栈入栈的操做
2. 若是主线程任务没有完成,继续完成,若是完成了就执行下一步
3. 系统读取队列任务, 开始执行
4. 不断循环

而咱们的异步任务中,分为宏任务(macrotask) 和微任务(microtask),
执行顺序
1. 先取出macrotask任务队列中的第一个任务进行执行
2. 取出Macrotask Queue中一个任务执行。
3. 取出Microtask Queue中任务执行直到清空。



node

执行任务为:
1. timers 阶段: 这个阶段执行setTimeout和setInterval预约的callback;
2. I/O callbacks 阶段: 执行除了 close事件的callbacks、被timers设定的callbacks、setImmediate()设定的callbacks这些以外的callbacks;
3. idle, prepare 阶段: 仅node内部使用;
4. poll 阶段: 获取新的I/O事件, 适当的条件下node将阻塞在这里;
5. check 阶段: 执行setImmediate() 设定的callbacks;
6. close callbacks 阶段: 执行socket.on('close', ...)这些 callback




参考文档,对比 setImmediate 和 process.nextTick()

setImmediate 和 process.nextTick()

setImmediate(() => console.log('immediate1'));
setImmediate(() => console.log('immediate2'));

setTimeout(() => console.log('setTimeout1'), 1000);
setTimeout(() => {
    console.log('setTimeout2');
    process.nextTick(() => console.log('nextTick1'));
}, 0);
setTimeout(() => console.log('setTimeout3'), 0);

process.nextTick(() => console.log('nextTick2'));
process.nextTick(() => {
    process.nextTick(console.log.bind(console, 'nextTick3'));
});
process.nextTick(() => console.log('nextTick4'));
复制代码
执行结果:

在控制台中执行node index.js,获得的结果以下:

nextTick2
nextTick4
nextTick3
setTimeout2
setTimeout3
nextTick1
immediate1
immediate2
setTimeout1
复制代码
结论

在node中,nextTick的优先级高于setTimeout和setImmediate(),因此会先执行nextTick里面的信息打印。
可是对于嵌套的nextTick,会慢于同步的nextTick,因此nextTick4会先于nextTick3
而后开始一个Event Loop过程,首先执行timer阶段,而此时setTimeout所须要等待的时间是0,因此当即执行setTimeout2和setTimeout3里面的逻辑。而setTimeout1因为设置了执行时间,不知足执行条件,被放到下一轮Event Loop
当前Event Loop执行到check阶段,因而打印出immediate一、immediate2
执行后面的Event Loop,当setTimeout1达到执行条件时执行

基于node事件的event loop,咱们使用事件也变得方便快捷

event.emit('eventType', () => {})
event.on('eventType', () => {})
相关文章
相关标签/搜索