美文网首页
2020-10-30 vue dep与watcher 异步队列

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

作者: 李华峰0722 | 来源:发表于2020-10-30 11:12 被阅读0次

    参考资料: 掘金小册 《剖析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
    }

    相关文章

      网友评论

          本文标题:2020-10-30 vue dep与watcher 异步队列

          本文链接:https://www.haomeiwen.com/subject/laarvktx.html