Brief Intro: JavaScript is a single thread lang, it can only do one thing at one tiem. Because of event loop, js thread isn’t blocked while running into asnychronous events.
- Event Loop
- Browser Event
- Node Event
事件循环
js 是单线程,任务分为同步和异步
异步情形:读取文件、网络请求等
异步任务回调通知
- 等待异步任务准备的同时,js 去执行其他同步任务,等待准备好了再去执行功能,也叫非阻塞式
- 实现 “通知” 的则是就是时间循环,它是计算机的一种机制
- 事件循环是由一个队列组成,异步任务回到先进先出,跟据队列任务的不同,分为宏任务和微任务
浏览器事件循环
由一个宏任务队列 + 多个微任务队列组成
- 第一个宏任务:全局 script 脚本。产生的宏任务和微任务进入各自队列中,执行完 script 后,清空当前微任务队列,完成一次事件循环;
- 再取出另外一个宏任务,把回调放入队列中,再清空微任务队列
- 宏任务队列只有一个,每一个宏任务都有自己的微任务队列,每轮循环都是由一个宏任务 + 多个微任务组成
1 | Promise.resolve().then(() => { |
Node 事件循环
由 6 个宏任务队列 + 6 个微任务队列组成
- 一个宏任务队列全部完成后,清空一次微任务队列,然后到下一个等级的宏任务队列,以此往复
- 一个宏任务队列搭配一个微任务队列,六个等级的宏任务全部完成后,才是一轮循环
- node 端宏微任务也有优先级先后:先 process.nextTick,后 promise.then 等
1 | console.log("Script开始"); |
node11.x 前后版本差异
前:取出一整个宏任务队列中全部任务,然后执行一个微任务队列
后:和浏览器类似,先执行一个宏任务,然后一个微任务队列。依然保留宏任务队列和微任务队列优先级
1 | console.log("Script开始"); |
宏任务
常见宏任务
- script(整体代码)
- setTimout:回调不一定在指定时间后执行,而是把回调放到事件循环队列中等待执行;0ms 默认最小时间为 4ms
- setInterval
- setImmediate (node 独有):用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数,setTimeout 优先级高于 setImmediate,也可以替代 setTimeout (0)
- requestAnimationFrame (浏览器独有)
- IO
- UI render(浏览器独有)
微任务
- process.nextTick (node 独有)
- Promise.then()
- Object.observe
- MutationObserver