nextTick 源码理解

nexttick 源码:

全局定义了一个 callbacks 数组 、 timerFunc、pending、isUsingMicroTask
接收两个参数: 回调函数 对象

1. 如果有回调函数,将回调函数包裹到一个函数中 ; 如果为空 resolve (对象);    放到callbacks 数组中

暴露一个nexttick 方法

export function nexttick(cb?:function, cxt?:object) {

   let _resolve

callbacks.push(()=> {

if(cb) {

try {

 cb.call(cxt)

} catch(err) {

console.log(err)

}

} else {

}

})

}

如果非空, 回调函数指向该对象cb.call(ctx);  // 指向ctx 并立马执行 但是现在被包含到了一个函数里面 所以需要外部函数执行 这个才会执行 就是上面代码里面的 copies[i]()

2 . 继续执行:判断pending是否为false, 如果是false, 表示nexttick 中还未开启任务队列;判断当前是否已经开启了任务队列, 如果为true 则不再重复执行,只把回调函数加入到callbacks数组里面就好了,

设置Pending 为true ,调用timerFunc函数; 

timerFunc 函数里面是一个异步函数调用,开启异步操作(微任务或者宏任务 需要等到调用栈清空之后执行) 具体见下面

3. 继续执行: 如果回调函数为空 并且支持promise, 返回一个promise 对象;

所以如果我们 console.log(this.$nexttick())返回的是一个promise 对象


timerFunc :主要是判断当前环境是否支持以下方法,使用所支持的第一种方法
if() {

支持promise promise.then

const p = new Promise()

  timerFunc   =  p.then((flushCallbacks)

微任务

}
else if(支持 MutationObserver) {

微任务

}
else if(支持setImmediate) {

timerFunc  =   setImmediate(flushCallbacks)


 else {

timerFunc  =   setTimeout(flushCallbacks,0)

}
然后在方法里面调用 flushCallbacks 方法
flushCallbacks:
这个方法是设置pending = fals以及开始定义的callbacks数组进行操作,对callbacks数组进行拷贝,防止原始的callbacks数组被更改造成影响;
对callbacks数组循环调用 

function flushCallbacks() {

pending = false

let copies = callbacks.slice(0)

callbacks.length = 0

for(let i = 0 ; i < copies .length; I ++) {

   copies[i]() // 函数执行

}

作用: vue 更新数据之类,在这里面可以立马获取到更新后的dom元素值;

vue 视图渲染是异步的 ,在同一事件循环的数据更新会放到同一个队列中,并进行去重工作,最终也是在nextTick 中的flushcallbacks执行dom 更新; 

Vue 中视图更新是异步的,当data数据修改之后,视图不会立马更新,而是开启一个缓冲队列,缓冲同一事件循环的更新事件,
最后调用nextTick 方法, 把更新视图的方法 放入到callbacks 数组中,开启异步任务(根据环境判断到底执行哪种任务,微任务、宏任务)
重要的是一个字段pending 判断当前是否已经开启了任务队列, 如果为true 则不再重复执行,只把回调函数加入到callbacks数组里面就好了,
最终会在异步任务中等待一起执行,
只有当执行该异步任务的时候 ,才会再次把pending设置为false, 同时callbacks 清空。再次执行下一次任务

学习参考:深入响应式原理 — Vue.jsVue.js - The Progressive JavaScript Frameworkhttps://cn.vuejs.org/v2/guide/reactivity.html#%E5%BC%82%E6%AD%A5%E6%9B%B4%E6%96%B0%E9%98%9F%E5%88%97

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值