持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
前言
一直在使用 vue 框架进行开发工作,心血来潮翻了翻源码,看到了 nextTick 的实现过程,借助本文记录下个人的理解。
代码理解
在 vue3 中,nextTick 的实现十分简单,核心只有四行代码,比起 vue2 简化了许多:
可以看到,nextTick 接受一个参数,名为 fn,是一个回调函数,在 p 执行完成之后调用,而 p 是 Promise.resolve() 函数。
总结下来的基本思路就是:因为在 vue 中,页面的更新是异步操作,所以通过 Promise.resolve(),在页面更新后的微任务中执行回调函数 fn,而 fn 就是使用者传入的回调函数,。
关键在于 p 的值,从代码中可以看到,要么是当前刷新的异步操作 currentFlushPromise,要么是普通的异步操作 resolvedPromise ,这两个定义如下:
resolvedPromise 是一个常量,而 currentFlushPromise 是一个变量,默认是 null , 而且可以被改变,在 queueFlush 中被重新赋值:
可以看出来,当不处于刷新列表(!isFlushing && !isFlushPending)时,会把 resolvedPromise.then(flushJobs) 赋值给 currentFlushPromise,resolvedPromise 上面说了是 Promise.resolve(),所以 currentFlushPromise 实际上就是 Promise.resolve().then(flushJobs)。
而 flushJobs 同样也是一个回调函数,主要用于刷新任务队列 queue,其实也就是执行任务队列中任务。
总结下来就是:如果当前存在任务列表 queue,会在 Promise.resolve() 之后,执行任务队列中任务,直到把列表清空为止,然后才执行使用者传入的回调函数 fn,也就是说此时的 p = Promise.resolve().then(flushJobs).then(fn) 。