「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」
浏览器中的事件循环
javascript的代码是在一个单独的线程中执行的,这就意味着代码是同步执行的,如果遇到阻塞,则代码将不能继续向下执行。
但是在我们的javascript中,有很多的异步代码,实际上这些代码不是由我们的js线程来完成的,是通过其他浏览器线程来完成耗时的操作,到等到要执行的时候,js线程只负责回调相应的异步代码,再放入js的执行栈中执行代码。
`事件循环:异步操作交给其他线程执行,执行完成后放入执行队列等待js线程的回调,整个执行过程就是事件循环。
宏任务和微任务
事件循环中并非只维护着一个队列,事实上是有两个队列:
宏任务队列(macrotask queue):ajax、setTimeout、setInterval、DOM监听、UI Rendering等
微任务队列(microtask queue):Promise的then回调、 Mutation Observer API、 queueMicrotask()等
执行顺序:
- main script中的代码优先执行(普通的同步代码)
- 执行微任务
- 在执行宏任务之前,要保证所有的微任务都执行完毕。
Node事件循环
一次完整的事件循环Tick分成很多个阶段:
- 定时器(Timers) :本阶段执行已经被 setTimeout() 和 setInterval() 调度的回调函数
- 待定回调(Pending Callback) :对某些系统操作(如TCP错误类型)执行回调,比如TCP连接时接收到 ECONNREFUSED
- idle, prepare:仅系统内部使用
- 轮询(Poll) :检索新的 I/O 事件;执行与 I/O 相关的回调;
- 检测(check) :setImmediate() 回调函数在这里执行
- 关闭的回调函数:一些关闭的回调函数,如:socket.on('close', ...)
node中的宏任务和微任务
宏任务(macrotask) :setTimeout、setInterval、IO事件、setImmediate、close事件;
微任务(microtask): Promise的then回调、process.nextTick、queueMicrotask;
node中的宏任务队列和微任务队列又分了好几个:
微任务队列:
- next tick queue:process.nextTick;
- other queue:Promise的then回调、queueMicrotask;
宏任务队列:
- timer queue: setTimeout , setInterval
- poll queue: IO事件;
- check queue: setImmediate
- close queue: colse 事件
所以执行顺序为:
- next tick queue:process.nextTick;
- other queue:Promise的then回调、queueMicrotask;
- timer queue: setTimeout , setInterval
- poll queue: IO事件;
- check queue: setImmediate
- close queue: colse 事件
\