剖析vue中nextTick源码

代码逻辑梳理:

  • callbacks 数组用于存储待执行的回调函数,waiting 变量用于标记是否有待执行的回调函数。

  • flushCallbacks 函数用于执行所有存储在 callbacks 数组中的回调函数,并在执行完成后将 waiting 设置为 false。

  • timer 函数根据环境选择合适的定时器来执行回调函数。优先选择 Promise 的微任务执行,如果不支持则尝试使用 MutationObserver,其次是 setImmediate,最后是默认的 setTimeout。

  • nextTick 函数用于将回调函数加入待执行队列,并触发执行。如果当前没有待执行的回调函数,则调用 timer 函数来触发执行,并标记有待执行的回调函数。

整体流程是将回调函数加入队列,通过选择合适的定时器来异步执行这些回调函数,保证它们在下一个微任务或宏任务中被执行

javascript 复制代码
let callbacks = [] // 存储待执行的回调函数
let waiting = false // 标记是否有待执行的回调函数

// 执行所有待执行的回调函数
function flushCallbacks() {
    callbacks.forEach((cb) => cb()) // 依次执行回调函数
    waiting = false // 标记执行完成
}

// 根据环境选择合适的定时器执行回调函数
function timer(flushCallbacks) {
    let timerFn = () => {} // 默认空函数

    // 使用 Promise
    if (typeof Promise !== 'undefined') {
        timerFn = () => {
            Promise.resolve().then(flushCallbacks) // 在微任务中执行回调函数
        }
    } else if (typeof MutationObserver !== 'undefined') { // 使用 MutationObserver
        let textNode = document.createTextNode(1)
        let observe = new MutationObserver(flushCallbacks)
        observe.observe(textNode, {
            characterData: true
        })
        timerFn = () => {
            textNode.textContent = 3
        }

    } else if (typeof setImmediate !== 'undefined') { // 使用 setImmediate
        timerFn = () => {
            setImmediate(flushCallbacks)
        }
    } else { // 默认使用 setTimeout
        timerFn = () => {
            setTimeout(flushCallbacks, 0)
        }
    }
    timerFn()
}

// 将回调函数加入待执行队列,并触发执行
function nextTick(cb) {
    callbacks.push(cb) // 将回调函数加入队列
    if (!waiting) {
        timer(flushCallbacks) // 触发执行回调函数
        waiting = true // 标记有待执行的回调函数
    }
}
相关推荐
汪子熙23 分钟前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
杨荧24 分钟前
【JAVA开源】基于Vue和SpringBoot的旅游管理系统
java·vue.js·spring boot·spring cloud·开源·旅游
Envyᥫᩣ32 分钟前
《ASP.NET Web Forms 实现视频点赞功能的完整示例》
前端·asp.net·音视频·视频点赞
Мартин.4 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
一 乐6 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
昨天;明天。今天。6 小时前
案例-表白墙简单实现
前端·javascript·css
数云界6 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd6 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常6 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer6 小时前
Vite:为什么选 Vite
前端