vue关于Scheduler

1,504 阅读1分钟

vue@2.6.10 src/core/observer/scheduler.js

Task: 事件循环中的一次宏任务或微任务

  此文件中包含的是与watcher相关的函数,queueWatcherflushSchedulerQueue,跟next-tick套路类似。

queueWatcher

  与nextTick方法类似,将watcher加入数组然后设置waiting=true,防止连续(在一次Task中多次)调用flushSchedulerQueue,flush结束后再将waiting复位。如果queue新的watcher时正在flush,则将watcher按照id大小插入queue中, 此处与angular脏检查递归检查dirty作用类似,都是将本批变化中产生的新变化与本批变化合并后再更新UI,也就是尽量将更新UI的操作集中

let vm = new Vue({
    data: {
        a: 1,
        b: 1,
        c: 1
    },
    watch: {
        a: function(nVal){
            this.b = nVal + 1;
        },
        b: function(nVal){
            this.c = nVal + 1;
        }
    }
})
vm.a = 2;
vm.b = 10;

bc的变化将发生在同一次queue清空过程中

line: 166
if (has[id] == null) {
      has[id] = true;
      ...
}

此处has防止queue中未执行的部分同时存在两个及以上相同id的watcher。由于插入新的watcher会根据watcher.id按从小到大插入,这样就会导致不同的写法可能会有不同的结果,如写成以下形式:

let vm = new Vue({
    data: {
        a: 1,
        b: 1,
        c: 1
    },
    watch: {
        b: function(nVal){
            this.c = nVal + 1;
        },
        a: function(nVal){
            this.b = nVal + 1;
        }
    }
})
vm.a = 2;
vm.b = 10;

如果b的watcher.id小于a的watcher.id,则b的watcher被执行2次,否则1次