Vue2剥丝抽茧-响应式系统之NextTick

前置知识

dom 更新

浏览器中有一个 js 引擎线程执行我们的 js 代码,同时还有一个 GUI 渲染线程来进行绘图,并且两个线程是互斥的,只能交替着进行。

而dom 更新是在 js 线程中进行的,因此 dom 更新了并不代表我们就一定可以看到,只有当渲染线程把更新的 dom 绘制完毕我们才会看到。

简单理解就是下边的样子:

举一个极端的例子,如果我们在 js 线程里修改了 dom ,但某种原因使得 js 线程一直在执行,没有轮到渲染线程,那么我们就永远看不到更新后 dom 了。

html 引入 bundle.js 。







Document






bundle.js 首先修改 dom ,然后执行一个死循环。

document.getElementById("root").innerText = "hello";
while (true) {}

此时页面就永远是空白了。但事实上我们的 dom 已经更新了,只是没有轮到渲染线程展示出来。

只更新最后一次结果

在 js 线程中如果修改同一个 dom 元素,无论修改多少次,最终轮到渲染线程的时候,渲染线程当前读到的 dom 是啥就会是啥。

document.getElementById("root").innerText = "hello";
document.getElementById("root").innerText = "hello2";
document.getElementById("root").innerText = "hello3";
document.getElementById("root").innerText = "liang";

上边 dom 变化了多次,但屏幕上只会看到 liang。

宏任务微任务任务队列

这里简单说一下,不细讲了。

  • 宏任务生成方式:script 标签, setTimeout, setInterval 等
  • 微任务生成方式:Promise, MutationObserver 等。

js 线程中,通过