• Vue源码之异步批量任务更新


    假设页面有四个地方需要更新属性,那我们希望不要更新四次,而是一次性更新。

    防止不停的更新
    把需要更新的watcher先存起来 放进一个异步队列
    把重复的watcher过滤掉  等待这轮更新完就清空队列 就是说等待主执行栈执行完了就执行异步任务,也可以理解为页面所有属性都赋值完再执行这个异步方法
    /**
     * 重要部分updata()方法
     * 加入页面有四个地方需要更新属性,那我们希望不要更新四次,而是一次性更新
     * 防止不停的更新
        把需要更新的watcher先存起来 放进一个异步队列queueWatcher,然后通过nextTick异步执行
        把重复的watcher过滤掉
        等待这轮更新完就清空队列 就是说等待主执行栈执行完了就执行异步任务,也可以理解为页面所有属性都赋值完再执行这个异步方法
     */
        updata(){ //如果立即调用get 会导致页面刷新频繁 用异步更新来解决
            // this.get()
            queueWatcher(this) //queueWatcher异步队列
        }
        run(){
            this.get()
        }
        
    }
    //渲染watcher、计算属性、vm.$watch 都属于Watcher实例
    export default Watcher
    
    function flushQueue () {
        queue.forEach(watcher => watcher.run) //执行更新
        //清空,下次使用
        has = {}
        queue = []
    }
    let has ={};
    let queue = []
    function queueWatcher(watcher){
        let id = watcher.id
        if(has[id] == null){
            has[id] =true
            queue.push(watcher) //相同的Watcher只会存一个到queue中
    
            //延迟清空队列
            // setTimeout(flushQueue,0) 这个方法也可以但vue内部原理是nextTick
            nextTick(flushQueue)
        }
    }
    let callbacks =[] //有可能用户也会写一个nextTick方法,这时候就需要把nextTick的回调函数放进一个数组里面,再依次执行,
    function nextTick(cb){
        callbacks.push(cb)
    
        //异步刷新这个callbacks 
        //异步任务先执行微任务在执行宏任务,微任务:Promise, mutationObserver, 宏任务:setImmediate setTimeout
        let timeFunc = () => {
            flushCallbacks()
        }
        //判断当前浏览器执行的异步方法
        if(Promise) {
            return Promise.resolve().then(timeFunc)
        }
        if(MutationObserver){ //创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用
            let observe = new MutationObserver(timeFunc);
            let textNode = document.createTextNode(1)
            observe.observe(textNode,{characterData:true})
            textNode.textContent(2)
            return
        }
        if(setImmediate) {
            return setImmediate(timeFunc)
        }
        //以上方法都不支持的时候就调用setTimeout setTimeout是宏任务,会在下一轮执行 事件循环机制的相关知识,但我们希望尽量再本轮执行,所以先判断支不支持微任务
        setTimeout(timeFunc,0)
    }
     
     
    不积跬步无以至千里
  • 相关阅读:
    网上Silverlight项目收集
    在Silverlight页面里显示HTML的免费控件下载(附使用方法代码)
    Silverlight SNS项目
    Visual Studio 2010下的RIA开发,Silverlight 4线下技术交流会期待您的参与!
    Windows7硬件展示与客户端信息收集
    Silverlight版的神奇罗盘,仿Google的Flash神奇罗盘
    (解题思路)Entity Framework 如动态创建表或者列
    (学)这些年来的几宗罪
    (学)在SQL2005中使用分区表技术
    (医)有痔青年的福音
  • 原文地址:https://www.cnblogs.com/lyt0207/p/12519184.html
Copyright © 2020-2023  润新知