Browse Source

完善异步更新意义的讲解,nextTick开篇

HcySunYang 7 years ago
parent
commit
1ed6517cba
1 changed files with 24 additions and 1 deletions
  1. 24 1
      docs/art/8vue-reactive-dep-watch.md

+ 24 - 1
docs/art/8vue-reactive-dep-watch.md

@@ -1169,6 +1169,8 @@ if (this.user) {
 
 ## 异步更新队列
 
+### 异步更新的意义
+
 接下来我们就聊一聊 `Vue` 中的异步更新队列。在上一节中我们讲解了触发依赖的过程,举个例子如下:
 
 ```html {2,12}
@@ -1342,7 +1344,28 @@ export function queueWatcher (watcher: Watcher) {
 let waiting = false
 ```
 
-为什么需要这个标志呢?我们看 `if` 语句块内的代码就知道了,在 `if` 语句块内先将 `waiting` 的值设置为 `true`,这意味着无论调用多少次 `queueWatcher` 函数,该 `if` 语句块的代码只会执行一次。接着调用 `nextTick` 并以 `flushSchedulerQueue` 函数作为参数,其中 `flushSchedulerQueue` 函数的作用之一就是用来将队列中的观察者统一执行更新的。
+为什么需要这个标志呢?我们看 `if` 语句块内的代码就知道了,在 `if` 语句块内先将 `waiting` 的值设置为 `true`,这意味着无论调用多少次 `queueWatcher` 函数,该 `if` 语句块的代码只会执行一次。接着调用 `nextTick` 并以 `flushSchedulerQueue` 函数作为参数,其中 `flushSchedulerQueue` 函数的作用之一就是用来将队列中的观察者统一执行更新的。对于 `nextTick` 相信大家已经很熟悉了,其实最好理解的方式就是把 `nextTick` 看做 `setTimeout(fn, 0)`,如下:
+
+```js {9}
+export function queueWatcher (watcher: Watcher) {
+  const id = watcher.id
+  if (has[id] == null) {
+    has[id] = true
+    // 省略...
+    // queue the flush
+    if (!waiting) {
+      waiting = true
+      setTimeout(flushSchedulerQueue, 0)
+    }
+  }
+}
+```
+
+我们完全可以使用 `setTimeout` 替换 `nextTick`,我们只需要执行一次 `setTimeout` 语句即可,`waiting` 变量就保证了 `setTimeout` 语句只会执行一次,这样 `flushSchedulerQueue` 函数将会在下一次事件循环开始时立即调用,但是既然可以使用 `setTimeout` 替换 `nextTick` 那么为什么不用 `setTimeout` 呢?原因就在于 `setTimeout` 并不是最优的选择,`nextTick` 的意义就是它会选择一条最优的解决方案,接下来我们就讨论一下 `nextTick` 是如何实现的。
+
+### nextTick 的实现
+
+
 
 
 ## 深度观测的实现