事件循环
宏任务和微任务
宏任务
指任务队列中的任务,如下:
- 整体的script代码(浏览器 和node)
- setTimeout (浏览器 和node)
- setInterval (浏览器 和node)
- setImmediate (node)
- requestAnimationFrame (浏览器)
- i/o (node)
setImmediate 可代替setTimeout('fun',0) ,并解决时间不准的问题
微任务
指需要异步执行的任务,执行时机是在主任务执行之后,当前宏任务结束之前,如下:
- promise.then catch finally (浏览器 和node)
- prcess.nextTick (node)
- MutationObserver (浏览器)
MutationObserver用于监听dom的改变,并在说有改变结束后 以数组的方式返回记录的结果 为什么需要微任务? 因为js是单线程的,所有任务都按照同一优先级顺序执行,会造成一些优先级任务的实时性问题,所以会出现微任务,通过将实时性要求较高的任务放在微任务队列中,从而保证高优先级任务的实时性要求。
同步任务和异步任务
广义分为 同步任务和异步任务
同步任务
指在主线程上排队执行的任务,一次只执行一个同步任务,执行完之后才会执行下一个同步任务。
异步任务
不进入主线程,而进入任务队列,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
为什么会有异步任务? 因为js是单线程的,如果只有同步任务,只有当前任务执行完之后,才会执行下一个任务,其他任务都处于等待状态,会造成下一个任务等待时间较长,通过异步任务就可以解决这个问题。
事件循环
浏览器的事件循环
同步异步: 同步和异步分别由event queue 和event table,当遇到同步的任务后,加入到同步的event queue中,如果有异步的任务加入到event table中,同步任务执行完后,通知对应的异步event table执行,执行完成后,再执行event queue 中的下一个任务。这样的执行过程形成了 event loop. 宏任务和微任务: js线程先执行当前宏任务,并同时开启一个微任务队列,遇到微任务时,先放到微任务队列中,宏任务执行完成看是否有微任务,如果有微任务先执行微任务队列,微任务队列执行完成后,再开启新的一轮宏任务。
示例:
setTimeout(() => {
//执行后 回调一个宏事件
console.log('内层宏事件3')
}, 0)
console.log('外层宏事件1');
new Promise((resolve) => {
console.log('外层宏事件2');
resolve()
}).then(() => {
console.log('微事件1');
}).then(()=>{
console.log('微事件2')
})
执行上面的代码过程:
- 将setTimeout到添加宏任务队列中;
- 执行"外层宏事件1" console
- 执行promise中的"外层宏事件2" console;
- 将then 中的"微事件1"中添加到微任务队列中;
- 将then中的"微事件2"中添加到微任务队列中;
- 执行微任务队列内容,"微事件1"、"微事件2" console;
- 进行宏任务队列中的 "内层宏事件3" console;
nodejs 的事件循环
node.js 中的事件循环分为各个阶段, 包括
- 定时器 timers
- io回调 io callbacks
- idle prepare 系统内部
- 轮询 检索新的io事件 poll
- 检测 setImmediate 回调 check
- 连接关闭 回调 如socket.on('close',...)
各个阶段组成一个大的循环,每个阶段内部都有一个fifo队列来执行回调。当事件循环进入给定的阶段时,它将执行于该阶段的任何操作,然后执行该阶段队列中的回调,直到队列用尽或最大回调已执行。当该队列已用尽或已达到最大回调限制,事件循环将移动到下一个阶段。 浏览器和nodejs的事件循环主要区别: 浏览器的微任务是在对应的宏任务中执行的,nodejs的微任务是在各个阶段之间执行的。
评论(0)
登录后参与评论。
还没有评论,来抢沙发吧。

