all files / vmodel/ Computed.js

93.22% Statements 55/59
66.67% Branches 12/18
100% Functions 12/12
93.22% Lines 55/59
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106                                                                    10×                                  
import { avalon } from '../seed/core'
 
import {
    obid,
    Mutation
} from './Mutation'
import {
    collectDeps
} from './transaction'
 
function getBody(fn) {
    var entire = fn.toString()
    return entire.substring(entire.indexOf('{}') + 1, entire.lastIndexOf('}'))
}
//如果不存在三目,if,方法
let instability = /(\?|if\b|\(.+\))/
 
function __create(o) {
    var __ = function() {}
    __.prototype = o
    return new __
}
 
function __extends(child, parent) {
    Eif (typeof parent === 'function') {
        var proto = child.prototype = __create(parent.prototype);
        proto.constructor = child
    }
}
export var Computed = (function(_super) {
    __extends(Computed, _super);
 
    function Computed(name, options, vm) { //构造函数
        _super.call(this, name, undefined, vm)
        delete options.get
        delete options.set
 
        avalon.mix(this, options)
        this.deps = {}
        this.type = 'computed'
        this.depsVersion = {}
        this.isComputed = true
        this.trackAndCompute()
        Eif (!('isStable' in this)) {
            this.isStable = !instability.test(getBody(this.getter))
        }
    }
    var cp = Computed.prototype
    cp.trackAndCompute = function() {
        if (this.isStable && this.depsCount > 0) {
            this.getValue()
        } else {
            collectDeps(this, this.getValue.bind(this))
        }
    }
 
    cp.getValue = function() {
        return this.value = this.getter.call(this.vm)
    }
 
    cp.schedule = function() {
        var observers = this.observers;
        var i = observers.length;
        while (i--) {
            var d = observers[i];
            if (d.schedule) {
                d.schedule()
            }
        }
    }
 
    cp.shouldCompute = function() {
        Eif (this.isStable) { //如果变动因子确定,那么只比较变动因子的版本
            var toComputed = false
            for (var i in this.deps) {
                if (this.deps[i].version !== this.depsVersion[i]) {
                    toComputed = true
                    this.depsVersion[i] = this.deps[i].version
                }
            }
            return toComputed
        }
        return true
    }
    cp.set = function() {
        Eif (this.setter) {
            avalon.transaction(this.setter, this.vm, arguments)
        }
    }
    cp.get = function() {
       
        //当被设置了就不稳定,当它被访问了一次就是稳定
        this.collect()
      
        if (this.shouldCompute()) {
            this.trackAndCompute()
                // console.log('computed 2 分支')
            this.updateVersion()
                //  this.reportChanged()
        }
 
        //下面这一行好像没用
        return this.value
    }
    return Computed
}(Mutation));