实现 nextTick

简介: 利用微任务与宏任务,派发延时任务。Vue 中 nextTick 的原理。实现 nextTick。

为什么需要 nextTick

在同一段逻辑中,上半段我们更新了视图,下半段又依赖上半段更新完以后的新视图,同步执行上半段逻辑与下半段逻辑,那一定是不可行的,我们需要将下半段逻辑作为一个延时任务放到下一次事件循环中执行。读伪代码也许更有助理解:

function init() {
  createMessageContainer() // 更新视图
  message.open() // 使用新的视图。这里会报错,因为依赖上面更新完后得到的新视图
}

// 于是我们希望可以派发一个延时任务
function init() {
  createMessageContainer() // 更新视图
  nextTick(() => {
    message.open() // 使用新的视图
  })
}

我们希望 nextTick 可以接收一个回调函数,这个回调函数包裹了我们希望在这一次事件循环结束以后执行的逻辑。

那么如何实现这个 nextTick 就是我们讨论的重点。

如何实现 nextTick

nextTick 需要将传入的回调函数包装成异步任务,异步任务分为宏任务与微任务,为了尽快执行,所以应该优先选择微任务。但是我们也需要考虑兼容性,最后我们选用 API 的优先级如下:

  1. Promise
  2. MutationObserver
  3. setImmediate
  4. setTimeout
function nextTick(callback) {
  let timerFunc;
  if (Promise可用) {
    // 使用 Promise
  } else if (MutationObserver可用) {
    // 使用 MutationObserver
  } else if (setImmediate可用) {
    // 使用 setImmediate
  } else {
    // 微任务都不被支持,使用 setTimeout
  }
  timerFunc(); // 派发延时任务
}

有了设计思路,实现起来易如反掌:

function nextTick(callback) {
  let timerFunc;
  if (typeof Promise !== 'undefined') {
    const p = Promise.resolve();
    timerFunc = () => {
      p.then(callback);
    };
  } else if (
    typeof MutationObserver !== 'undefined' &&
    MutationObserver.toString() === '[object MutationObserverConstructor]'
  ) {
    let counter = 1;
    const observer = new MutationObserver(callback);
    const textNode = document.createTextNode(String(counter));
    observer.observe(textNode, { characterData: true });
    timerFunc = () => {
      counter = (counter + 1) % 2;
      textNode.data = String(counter); // 数据更新
    };
  } else if (typeof setImmediate !== 'undefined') {
    timerFunc = () => {
      setImmediate(callback);
    };
  } else {
    timerFunc = () => {
      setTimeout(callback, 0);
    };
  }
  timerFunc();
}

总结

读到这里你应该已经发现以上就是 Vue 中 nextTick 的原理了~

异步任务的巧妙使用可以帮助我们更好的玩转 JavaScript~

相关文章
|
消息中间件 Apache 数据安全/隐私保护
[ActiveMQ]修改默认密码
ActiveMQ使用的是jetty服务器, 在ActiveMQ目录下的conf/jetty.xml文件,vim打开 将property name为authenti...
2798 0
|
C语言 C++
第一个c语言程序
第一个c语言程序
105 0
|
关系型数据库 Linux 网络安全
很详细的PostgreSQL安装部署教程
很详细的PostgreSQL安装部署教程
2319 0
|
存储 Java
JavaFX【TableView使用详解】
JavaFX【TableView使用详解】
|
JavaScript API 数据格式
Vue 实战 饿了么 (一)
当Vue实例没有el属性时,则该实例尚没有挂载到某个dom中;假如需要延迟挂载,可以在之后手动调用vm.$mount()方法来挂载。
2597 0
|
Linux Android开发 C++
linux安装Eclipse c++环境
yum install eclipse     yum install eclipse-cdt
1012 0
|
18天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
6839 30
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
3天前
|
数据采集 人工智能 前端开发
让 Coding Agent 从黑盒到透明:阿里云 Agent 观测审计数据采集实践
AI Agent 规模化落地带来执行黑盒、行为难追溯、成本难度量三大难题。阿里云基于 OTel 标准,面向 Coding Agent、个人通用助理和框架型 Agent,推出 LoongSuite Pilot、插件及探针等无侵入采集方案,让 Agent 实现可看见、可分析、可审计、可治理。
609 138