从源码看Vue2中 nextTick 原理

58 阅读1分钟
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
<script>
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]()
  }
}

let microTimerFunc
const p = Promise.resolve()
microTimerFunc = () => {
  // 在微任务中异步执行 flushCallbacks
  p.then(flushCallbacks)
}

function nextTick(cb, ctx){
  // 收集 nextTick 中的方法
  callbacks.push(() => {
    if(cb) {
      cb.call(ctx)
    }
  })
  // 调用两次 nextTick ,只会执行一次 flushCallbacks 方法
  if(!pending) {
    pending = true
    microTimerFunc()
  }
}

nextTick(function(){
  // Berwin
  console.log(this.name);
}, {name: 'Berwin'})
</script>
</body>
</html>