vue源码中的nextTick是怎样实现的

一、Vue.nextTick 内部逻辑

在执行 initGlobalAPI(Vue) 初始化 Vue 全局 API 中,这么定义 Vue.nextTick

function initGlobalAPI(Vue) {
   
    //...
    Vue.nextTick = nextTick;
}

可以看出是直接把 nextTick 函数赋值给 Vue.nextTick,就可以了,非常简单。

二、vm.$nextTick 内部逻辑

Vue.prototype.$nextTick = function (fn) {
   
    return nextTick(fn, this)
};

可以看出是 vm.$nextTick 内部也是调用 nextTick 函数。

三、前置知识

nextTick 函数的作用可以理解为异步执行传入的函数,这里先介绍一下什么是异步执行,从 JS 运行机制说起。

1、JS 运行机制

JS 的执行是单线程的,所谓的单线程就是事件任务要排队执行,前一个任务结束,才会执行后一个任务,这就是同步任务,为了避免前一个任务执行了很长时间还没结束,那下一个任务就不能执行的情况,引入了异步任务的概念。JS 运行机制简单来说可以按以下几个步骤。

  • 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
  • 主线程之外,还存在一个任务队列(task queue)。只要异步任务有了运行结果,会把其回调函数作为一个任务添加到任务队列中。
  • 一旦执行栈中的所有同步任务执行完毕,就会读取任务队列,看看里面有那些任务,将其添加到执行栈,开始执行。
  • 主线程不断重复上面的第三步。也就是常说的事件循环(Event Loop)。

2、异步任务的类型

nextTick 函数异步执行传入的函数,是一个异步任务。异步任务分为两种类型。

主线程的执行过程就是一个 tick,而所有的异步任务都是通过任务队列来一一执行。任务队列中存放的是一个个的任务(task)。规范中规定 task 分为两大类,分别是宏任务(macro task)和微任务 (micro task),并且每个 macro task 结束后,都要清空所有的 micro task。

用一段代码形象介绍 task的执行顺序。

for (macroTask of macroTaskQueue) {
   
    handleMacroTask();
    for (microTask of microTaskQueue) {
   
        handleMicroTask(microTask);
    }
}

参考Vue3源码视频讲解:进入学习

在浏览器环境中,
常见的创建 macro task 的方法有

  • setTimeout、setInterval、postMessage、MessageChannel(队列优先于setTimeiout执行)
  • 网络请求IO
  • 页面交互:DOM、鼠标、键盘、滚动事件
  • 页面渲染
    常见的创建 micro task 的方法
  • Promise.then
  • MutationObserve
  • process.nexttick

nextTick 函数要利用这些方法把通过参数 cb 传入的函数处理成异步任务。

三、 nextTick 函数

var callbacks = [];
var pending = false;
function nextTick(cb, ctx) {
   
    var _resolve;
    callbacks.push(function() {
   
        if (cb) {
   
            try {
   
                cb.call(ctx);
            } catch (e) {
   
                handleError(e, ctx, 'nextTick');
            }
        } else if (_resolve) {
   
            _resolve(ctx);
        }
    });
    if (!pending) {
   
        pending = true;
        timerFunc();
    }
    if (!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值