一、浏览器异步策略
1、当我们执行 JS 代码的时候其实就是往执行栈(同步) (Call Stack) 中放入函数;
2、遇到异步代码的时候该怎么办?其实当遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) 队列中(异步的Task: 有宏任务Task, 和 微任务Task);
3、一旦执行栈为空,Event Loop 就会从 Task 队列中拿出需要执行的代码并放入执行栈中执行,所以本质上来说 JS 中的异步还是同步行为。
一、Event Loop
执行顺序如下所示:
- 首先执行同步代码,这属于宏任务
- 当执行完所有同步代码后,执行栈call stack 为空,查询是否有异步代码需要执行
- 执行所有微任务
- 当执行完所有微任务后,如有必要会渲染页面(渲染)
- 然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数
二、微任务 (在渲染页面前)
包括 process.nextTick ,异步(promise ,MutationObserver) 。
三、宏任务(在渲染页面后)
包括 script ,异步( setImmediate, setTimeout ,setInterval) ,I/O ,UI rendering 。
四、误区****
这里很多人会有个误区,认为微任务快于宏任务,其实是错误的。
因为宏任务中包括了 script ,浏览器会先执行一个宏任务, 接下来有异步代码的话才会先执行微任务。
五、正确顺序:
开始1个宏任务->再是微任务->再是浏览器渲染一次页面->再开始另一个宏任务,再是微任务,再是渲染。
如果微任务 microtask queue 没有清空 ,下一个宏任务不会开始
二、Vue源码-异步更新
Vue高效的秘诀是一套批量、异步的更新策略。
1、策略
异步:只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
批量:如果同一个 watcher 被多次触发,只会被推入到队列中一次。去重对于避免不必要的计算 和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列执行实际工作。
异步策略:Vue 在内部对异步队列尝试使用原生的 Promise.then 、 MutationObserver 或
setImmediate ,如果执行环境都不支持,则会采用 setTimeout 代替。
2、异步更新思维导图
3、指导绘制