关于这个函数的一个疑问

来源:5-8 组件更新(2)

旋涡鸣人_

2019-01-31

export function nextTick (cb?: Function, ctx?: Object) {
  let _resolve
  callbacks.push(() => {
    if (cb) {
      try {
        cb.call(ctx)
      } catch (e) {
        handleError(e, ctx, 'nextTick')
      }
    } else if (_resolve) {
      _resolve(ctx)
    }
  })
  if (!pending) {
    pending = true
    if (useMacroTask) {
      macroTimerFunc()
    } else {
      microTimerFunc()
    }
  }
  // $flow-disable-line
  if (!cb && typeof Promise !== 'undefined') {
    return new Promise(resolve => {
      _resolve = resolve
    })
  }
}

关于pending 的理解 ,每一次 nextTick() 会把函数包装扔到队列中,
pending 为false ,则添加到任务队列之后,设置为 pending true,由于接下来是异步的,所以又可能这期间又又nexttick 进来,这时候进来,就不会重新设置任务队列了,只是添加到同一个任务队列中。

但是如果 以及到了 执行阶段的话 表示已经在执行任务阶段,那就把pending 设为 false, 由于已经在执行了,所以 必须另起一个任务调度。老师这么理解对不对。。。

写回答

1回答

ustbhuangyi

2019-02-01

这么理解可能会更加清晰
1. nextTick 函数设计的目的是让所有通过 nextTick 执行的函数 cb 异步执行,也就是在下一个 tick 执行。
2. 调用 nextTick 的 cb 不会立马执行,会收集到一个 callbacks 数组中
3. macroTimerFunc 或者 microTimerFunc 就是在下一个 tick 去遍历 callbacks 数组执行。
4. 显然,在一个同步 tick 内,即使 nextTick 函数被多次执行,但是 macroTimerFunc 或者 microTimerFunc 并不需要多次执行,所以需要一个 pending 标志位来保证他们只执行一次。
5. 当 callbacks 数组在下一个 tick 执行后,需要重置 pending,保证之后执行 nextTick 的逻辑正确。

0
1
旋涡鸣人_
非常感谢!
2019-02-01
共1条回复

Vue.js 源码深入解析 深入理解Vue实现原理

全方位讲解 Vue.js 源码,进阶高级工程师

4986 学习 · 1038 问题

查看课程