玩转Vuejs--异步队列那点事

引言:

前面核心篇说过Vue 运行时的核心主要包括数据初始化、数据更新、异步队列、DOM渲染这几个部分,理解异步队列是理解数据更新非常重要的一部分,本文讲一下Vue的异步队列的思路以及实现原理,顺带讲一下  Vue 的 $nextTick。

一、Vue的异步队列是什么?

//从前面的分析我们知道,Vue 初始化后一般会创建不止一个 watcher ,包括渲染watcher 、computed 、watch中为每个属性创建的 watcher

Vue 中当侦听到数据变化进行更新时,对应的 watcher 并不会被直接执行,而是会被放入一个队列中在下一个事件循环中执行,并且执行的过程是一个异步执行,这个队列就是异步队列。

二、异步队列实现原理

Vue的异步队列是在数据更新时开启的,那么从数据更新的逻辑开始看

 1 /**
 2    * Define a reactive property on an Object.
 3    */
 4   function defineReactive$$1 (
 5     obj,
 6     key,
 7     val,
 8     customSetter,
 9     shallow
10   ) {
11     var dep = new Dep();
12 
13     var property = Object.getOwnPropertyDescriptor(obj, key);
14     if (property && property.configurable === false) {
15       return
16     }
17 
18     // cater for pre-defined getter/setters
19     var getter = property && property.get;
20     var setter = property && property.set;
21     if ((!getter || setter) && arguments.length === 2) {
22       val = obj[key];
23     }
24 
25     var childOb = !shallow && observe(val);
26     Object.defineProperty(obj, key, {
27       enumerable: true,
28       configurable: true,
29       get: function reactiveGetter () {
30         var value = getter ? getter.call(obj) : val;
31         if (Dep.target) {
32           dep.depend();
33           if (childOb) {
34             childOb.dep.depend();
35             if (Array.isArray(value)) {
36               dependArray(value);
37             }
38           }
39         }
40         return value
41       },
42       set: function reactiveSetter (newVal) {
43         var value = getter ? getter.call(obj) : val;
44         /* eslint-disable no-self-compare */
45         if (newVal === value || (newVal !== newVal && value !== value)) {
46           return
47         }
48         /* eslint-enable no-self-compare */
49         if (customSetter) {
50           customSetter();
51         }
52         // #7981: for accessor properties without setter
53         if (getter && !setter) { return }
54         if (setter) {
55           setter.call(obj, newVal);
56         } else {
57           val = newVal;
58         }
59         childOb = !shallow && observe(newVal);
60         dep.notify(); 
61       }
62     });
63   }
 
  Dep.prototype.notify = function notify () {
    // stabilize the subscriber list first
    var subs = this.subs.slice();
    if (!config.async) {
      // subs aren't sorted in scheduler if not running async
      // we need to sort them now to make sure they fire in correct
      // order
      subs.sort(function (a, b) { return a.id - b.id; });
    }
    for (var i = 0, l = subs.length; i < l; i++) {
      subs[i].update();  //watcher.update()
    }
  };

可以看到 当 数据发生变化时会通过调用 

猜你喜欢

转载自www.cnblogs.com/DevinnZ/p/11065645.html