• 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 操作进行更新。

  • 相关阅读:
    PHP Jquery
    PHP TPinfo表的增删改查
    PHP TP验证码
    PHP TP表单验证
    PHP TP增删改
    8月21日 仿163邮箱中遇到的问题及解决(三)
    8月20日 仿163邮箱中遇到的问题及解决(二)
    8月12日 仿163邮箱中遇到的问题及解决(一)
    8月7日 使用Jquery做表格的隔行变色,点击事件
    6月17日 TP表单验证
  • 原文地址:https://www.cnblogs.com/3body/p/13217722.html
Copyright © 2020-2023  润新知