2020-10-30 vue dep与watcher 异步队列

2020-10-30  本文已影响0人  李华峰0722

参考资料: 掘金小册 《剖析Vue.js内部运行机制》

<div id="app">
  <div>{{ number }}</div>
  <div>{{ hahaha }}</div>
</div>
<div id="app2">
  <div>{{ number }}</div>
  <div>{{ hahaha }}</div>
</div>

  const data = {
    message: 'Hello Vue!',
    a: 1
  }
  const app = new Vue({
    el: '#app',
    data: data
  })
  const app2 = new Vue({
    el: '#app2',
    data: data
  })

一个视图(
<div id="app">
<div>{{ number }}</div>
<div>{{ hahaha }}</div>
</div>
)对应一个watcher watcher在编译模板时候生成 watcher生成的时候会调用使用到的数据的get方法 从而将该watcher放到dep中

number: 0 dep1
msg: 'hahaha' dep2

一个数据对应一个dep

当数据改变时,会调用对应数据的set方法 从而dep.notify->watcher.update

依赖收集的结果为
dep1收集了 watcher1 watcher2
dep2收集了 watcher1 watcher2

例如: 这里number = 1 会dep1.notify->watcher1.update(视图1#app的更新),watcher2.update(视图2#app2的更新)

watcher1.update->watcher1.queueWatcher(watcher1)

三个队列

queue 用于存放watcher

callbacks 用于存放flushScdulerQueueFn【用于存放处理queue的函数】

settimeout队列【异步队列】 用于存放flushCallbacksFn【用于存放处理callbacks的函数】

queue = []
waiting = false

queueWatcher (watcher) {
queue.push(watcher) //判重加入watcher

if(!waiting) {
waiting = true
nextTick(flushScdulerQueueFn)
}
}

flushScdulerQueueFn() {
//处理queue数组中的每一项 并且调用watcher.run() 处理过的watcher从queue中移除
waiting = false
}

callbacks = []
pending = false

nextTick (cb) {
callbacks.push(cb)
if(!pending) {
pending = true
settimeout(flushCallbacksFn,0)
}
}

flushCallbacksFn () {
pending = false
// 处理callbacks数组中的每一项 并且调用flushScdulerQueueFn
}

上一篇 下一篇

猜你喜欢

热点阅读