vue-尤雨溪讲课系列二

dependence tracking 实现依赖跟踪
??这是什么意思??
举个例子:
a = 10;
b= a*3
要求当a改变了b同时跟着改变, b依赖于a 这就是依赖跟踪 。 a是被依赖项。

要求:

  • Create a Dep class with two methods: depend and notify.
  • Create an autorun function that takes an updater function.
  • Inside the updater function, you can explicitly depend on an instance of Dep by calling dep.depend()
  • Later, you can trigger the updater function to run again by calling `dep.notify()
  1. 创建一个Dep类,它有两个方法depend() 和notify()
  2. 创建一个autorun 函数,参数接受一个更新函数 update()
  3. depend() 当前正在执行的代码,收集订阅者
  4. notify() 依赖发生改变 ,依赖于它的对象(计算 数据 表达式)被通知更新。

这里其实是创建一个小型的订阅系统。
autorun 其实就是订阅者了才能被通知。

vue-尤雨溪讲课系列二
还有一个会误解的知识点,
先解决:

let a = new Set()

        function x() {
            console.log(1234);
        }
        a.add(x)
        a.forEach(subscriber => subscriber())

一开始我有点蒙,这个subscrber()是一个Set的函数吗?
后来实践一下是 x(){}
其实就是forEach语法 subscriber = x ,x+()不就是执行x()的意思吗。。。。

	window.Dep = class Dep {
            constructor() {
                this.subscribers = new Set()
            }

            depend() {
                if (activeUpdate) {
                    // register the current active update as a subscriber
                    this.subscribers.add(activeUpdate)
                    //把activeUpdate函数加入订阅器 其实
                }
            }

            notify() {
                // run all subscriber functions
                console.log(this.subscribers);
                this.subscribers.forEach(subscriber => subscriber())
                //通知订阅者运行update函数
            }
        }

        let activeUpdate

        function autorun(update) {
            function wrappedUpdate() {
                activeUpdate = wrappedUpdate
                update()
                activeUpdate = null
            }
            wrappedUpdate()
        }

把上一节的合并起来:


<body>
    <input type="text" id="in" />
    <div id='countview'></div>
    <script>
        function isObject(obj) {
            return typeof obj === 'object' &&
                !Array.isArray(obj) &&
                obj !== null &&
                obj !== undefined
        }

        function observe(obj) {
            if (!isObject(obj)) {
                throw new TypeError()
            }

            Object.keys(obj).forEach(key => {
                let internalValue = obj[key]
                let dep = new Dep()
                Object.defineProperty(obj, key, {
                    get() {
                        dep.depend() //加人依赖收集
                        return internalValue
                    },
                    set(newValue) {
                        const isChanged = internalValue !== newValue
                        if (isChanged) {
                            internalValue = newValue
                            dep.notify()
                        }
                    }
                })
            })
        }

        window.Dep = class Dep {
            constructor() {
                this.subscribers = new Set()
            }

            depend() {
                if (activeUpdate) {
                    // register the current active update as a subscriber
                    this.subscribers.add(activeUpdate)
                }
            }

            notify() {
                // run all subscriber functions
                console.log(this.subscribers);
                this.subscribers.forEach(subscriber => subscriber())
            }
        }

        let activeUpdate

        function autorun(update) {
            function wrappedUpdate() {
                activeUpdate = wrappedUpdate
                update()
                activeUpdate = null
            }
            wrappedUpdate()
        }


        const state = {
            count: 0,
        }
        let cv = document.getElementById('countview');
        let inp = document.getElementById('in');
        inp.oninput = function(e) {
            state.count = this.value;
        }
        observe(state); //观察者开始观察state

        autorun(() => { //该函数相当于订阅者
            cv.innerHTML = state.count; // 触发通知时候要做的事
            inp.value = state.count;
        })
    </script>
</body>

效果
vue-尤雨溪讲课系列二

绑定原理,
实质上订阅者应该还要写,用于视图。也就是watcher。继续看尤大神视频。

上一篇:看完CSAPP,我人麻了


下一篇:第二章 Publisher 和 Subscriber (Part. 1)