美文网首页Web 前端开发
nextTick异步执行任务

nextTick异步执行任务

作者: 灰灰0421 | 来源:发表于2017-04-01 14:58 被阅读0次

    最近开始看尤雨溪大神的vue源码,这算是开篇吧。打算从第一个版本开始,一个一个开始看,将看到的收获记录下来,也好督促自己坚持下去。

    适用场景:大家都知道js是单线程的,而一些不是很重要的任务,为了不影响主要逻辑的运行,可以放在线程空闲后执行。譬如我之前遇到过的日志记录,可以等待页面渲染完成后再向后台发送请求。
    因为看的是第一个版本,版本号是a879ec0。从源码中删除了一些跟本主题无关的代码,如下:

    var nextTick = (function () {
    
        // 保存回调方法的队列
        var callbacks = []
    
        // 这个变量很值得玩味,下面解释
        var pending = false
    
        // 如果支持setImmediate方法则使用,不支持则用setTimeout
        // setImmediate是微软开发的,IE10以上支持,这里不详细解释,因为我也不是很懂,哈哈
        var timerFunc = window.setImmediate || setTimeout;
    
        // 执行回调方法队列
        function nextTickHandler () {
    
            // 置为false,以后可以创建新的任务
            pending = false
    
            // 复制队列,用这个方法复制确实不错,高效
            var copies = callbacks.slice(0)
    
            // 清空原有队列
            callbacks = []
            for (var i = 0; i < copies.length; i++) {
                copies[i]()
            }
        }
    
        return function (cb, ctx) {
    
            // cb 任务方法
            // ctx cb的执行环境
            var func = ctx
                ? function () { cb.call(ctx) }
                : cb
    
            // 压入队列
            callbacks.push(func)
    
            // pending为true,表示任务已经创建
            // pending为false,任务没创建,需要创建
            if (pending) return
            pending = true
    
            // 创建任务
            timerFunc(nextTickHandler, 0)
        }
    })();
    

    setTimeout会在线程空闲时立刻执行任务队列。
    这里的任务方法没有添加参数,因为在该版本中没有这个必要,这里我小小修改了一下

    var nextTick2 = (function () {
        var callbacks = []
        var pending = false
        var timerFunc = window.setImmediate || setTimeout;
        function nextTickHandler () {
            pending = false
            var copies = callbacks.slice(0)
            callbacks = []
            for (var i = 0; i < copies.length; i++) {
                copies[i]()
            }
        }
    
        return function (cb, ctx ,args) {
            var func = ctx
                ? function () { cb.call(ctx,args) }
                : function () { cb(args) };
            callbacks.push(func)
            if (pending) return
            pending = true
            timerFunc(nextTickHandler, 0)
        }
    })();
    

    这样将参数args传入就能执行了。
    当然这还只是vue的第一个版本,很多东西我还是看的云里雾里,整个结构还没有梳理成型,和大神的差距好大啊啊啊啊。。。。
    后续版本如果有更好的解决方案我会继续更新。

    本文内容纰漏之处请各位指正,谢谢!

    祝爸爸妈妈身体健康!

    相关文章

      网友评论

        本文标题:nextTick异步执行任务

        本文链接:https://www.haomeiwen.com/subject/opuiottx.html