VUE中有一个方法 nextTick,它的作用是将函数推到下一个事件循环再执行。我们在开发中经常用到它,比如某些操作要等页面渲染更新后再执行,这时候就用this.$nextTick()。同时vue内部也常用到它,比如监听数据变化时不会每次都触发更新,而是将更新任务放在一个异步队列中,最终只触发一次更新。
我们来模拟nextTick的实现原理,将其写成一个简化版本:
let callbacks = [];
let pending = false;
function nextTick(cb) {
callbacks.push(cb);
if (!pending) {
pending = true;
timeFunc();
}
}
function timeFunc() {
setTimeout(() => {
flushQueue();
}, 0)
}
function flushQueue() {
const copies = callbacks.slice(0);
// 之所以拷贝数组,是考虑某些情况下会有嵌套使用nextTick的场景
// 若不拷贝,则嵌套的nextTick任务会被推入任务队列,在本次事件循环执行
callbacks.length = 0;
pending = false;
copies.forEach(cb => cb());
}
console.log(1);
nextTick(() => {
console.log(2);
nextTick(() => console.log(3))
});
nextTick(() => console.log(4));
console.log(5);
// 打印顺序应该是 1 5 2 4 3
在node环境下直接运行,查看结果,和我们预期的一致: