全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 6 分钟 ✍️ juanwangdev

异步更新队列

Vue 在检测到数据变化后,不会立即更新 DOM,而是将更新操作放入异步队列,在下一个事件循环中批量执行。

为什么需要异步更新

JavaScript
// 同步更新的问题
this.count = 1
this.count = 2
this.count = 3
// 如果每次变化都更新DOM,会触发3次渲染

Vue 将多次数据变化合并为一次 DOM 更新,提升性能。

nextTick 实现

JavaScript
const callbacks = []
let pending = false

function flushCallbacks() {
  pending = false
  const copies = callbacks.slice(0)
  callbacks.length = 0
  for (let i = 0; i < copies.length; i++) {
    copies[i]()
  }
}

// 优先使用微任务(Promise/MutationObserver)
let timerFunc
if (typeof Promise !== 'undefined') {
  const p = Promise.resolve()
  timerFunc = () => p.then(flushCallbacks)
} else {
  // 降级为宏任务 setTimeout
  timerFunc = () => setTimeout(flushCallbacks, 0)
}

function nextTick(cb) {
  callbacks.push(cb)
  if (!pending) {
    pending = true
    timerFunc()
  }
}

Watcher 的异步更新

JavaScript
class Watcher {
  update() {
    // 将更新放入队列
    queueWatcher(this)
  }
}

const queue = []
const has = {}

function queueWatcher(watcher) {
  const id = watcher.id
  if (has[id] == null) {
    has[id] = true
    queue.push(watcher)
    // 下一个tick统一执行
    nextTick(flushSchedulerQueue)
  }
}

function flushSchedulerQueue() {
  // 按优先级排序
  queue.sort((a, b) => a.id - b.id)
  for (let i = 0; i < queue.length; i++) {
    queue[i].run()
  }
  queue.length = 0
}

使用 nextTick

JavaScript
// 场景:数据更新后立即操作DOM
this.message = 'updated'
// 此时DOM还未更新
console.log(this.$el.textContent) // 旧值

this.$nextTick(() => {
  console.log(this.$el.textContent) // 新值
})

// 或使用 async/await
await this.$nextTick()
console.log(this.$el.textContent)

Vue 3 的 flushQueue

JavaScript
import { nextTick, ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
  // DOM 还未更新
  nextTick(() => {
    // DOM 已更新
  })
}

事件循环中的执行顺序

text
同步代码执行 → 微任务执行(Promise.then)→ DOM更新 → 宏任务执行(setTimeout)
     ↑                                    ↑
  this.count = 1                    nextTick 回调

要点总结

  • Vue 将DOM更新放入异步队列,批量执行避免重复渲染
  • 优先使用微任务(Promise),降级使用宏任务(setTimeout)
  • 多个相同 Watcher 的更新会被去重合并
  • $nextTick 用于获取更新后的DOM状态

📝 发现内容有误?点击此处直接编辑

← 上一篇 响应式原理
下一篇 → 组件渲染优化
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库