zoukankan      html  css  js  c++  java
  • Vue 中批量异步更新 nextTick 解读

    批量更新代码示例:

    let uid = 0;
    
    class Watcher {
        constructor () {
            this.id = ++uid;
        }
    
        update () {
            console.log('watch' + this.id + ' update');
            queueWatcher(this);
        }
    
        run () {
            console.log('watch' + this.id + '视图更新啦~');
        }
    }
    
    let callbacks = [];
    let pending = false;
    
    function nextTick (cb) {
        callbacks.push(cb);
    
        if (!pending) {
            pending = true;
            setTimeout(flushCallbacks, 0);
        }
    }
    
    function flushCallbacks () {
        pending = false;
        const copies = callbacks.slice(0);
        callbacks.length = 0;
        for (let i = 0; i < copies.length; i++) {
            copies[i]();
        }
    }
    
    let has = {};
    let queue = [];
    let waiting = false;
    
    function flushSchedulerQueue () {
        let watcher, id;
    
        for (index = 0; index < queue.length; index++) {
            watcher = queue[index]
            id = watcher.id;
            has[id] = null;
            watcher.run();
        }
    
        waiting  = false;
    }
    
    function queueWatcher(watcher) {
        const id = watcher.id;
        if (has[id] == null) {
            has[id] = true;
            queue.push(watcher);
    
            if (!waiting) {
                waiting = true;
                nextTick(flushSchedulerQueue);
            }
        }
    }
    
    (function () {
        let watch1 = new Watcher();
        let watch2 = new Watcher();
    
        watch1.update();
        watch1.update();
        watch2.update();
    })();

    解读:

    当 setter 的时候会将对应的 watcher push 到 queue 中,然后通过一个开关变量 waiting 执行 nextTick,而 nextTick 会使用 setTimeout 开启一个定时器,这个定时器将遍历 queue 中的 watcher 进行 run 操作。这些操作由于是在定时器中执行,所以会移交到主线程执行完毕之后的 event loop 中执行。而在主线程中会继续有其它 setter 操作,往 queue 中 push 其它的 watcher,只是此时开关 waiting 已经关闭,所以不会执行新的 nextTick,也就不会开启更多的定时器,一次 tick 就只有一个 setTimeout 定时器。当主线程中所有 setter 操作执行完毕后,queue 中也就有了这次要更新的所有 watcher,然后等待主线程中的代码执行完毕开始执行 event loop,event loop 中遍历 queue 执行所有 watcher 的 run 后,会把开关 waiting 开启,然后开始等下下一轮的 setter 操作进行更新。

  • 相关阅读:
    es5预览本地文件、es6练习代码演示案例
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 836 矩形重叠(暴力)
    Subversion under Linux [Reprint]
    Subversion how[Reprint]
  • 原文地址:https://www.cnblogs.com/3body/p/13217722.html
Copyright © 2011-2022 走看看