Vue2核心原理(简易版)-异步更新
什么是异步更新?
为什么要异步更新?
vue.js异步更新如何实现
- 调度器的具体实现
// observer/scheduler.js
import { nextTick } from "../utils";
let queue = [];
let has = {}; // 做列表的 列表维护存放了哪些watcher
// 动画 滚动的频率高,节流 requestFrameAnimation
function flushSchedulerQueue(){
for(let i =0 ; i < queue.length; i++){
queue[i].run(); // vm.name = 123?
}
queue = [];
has = {};
pending = false;
}
let pending = false;
// 要等待同步代码执行完毕后 才执行异步逻辑
export function queueWatcher(watcher) { // 当前执行栈中代码执行完毕后,会先清空微任务,在清空宏任务, 我希望尽早更新页面
const id = watcher.id; // name 和 age的id 是同一个
if (has[id] == null) {
queue.push(watcher);
has[id] = true;
// 开启一次更新操作 批处理 (防抖)
if(!pending){
nextTick(flushSchedulerQueue, 0);
pending = true;
}
}
}
- nextTick具体实现,vue2兼容了各种浏览器的适配情况,按照微任务的优先级制作了一个timer方法。
// utils.js
const callbacks = [];
function flushCallbacks() {
callbacks.forEach((cb) => cb());
waiting = false;
}
let waiting = false;
function timer(flushCallbacks) {
let timerFn = () => {};
if (Promise) {
timerFn = () => {
Promise.resolve().then(flushCallbacks);
};
} else if (MutationObserver) {
let textNode = document.createTextNode(1);
let observe = new MutationObserver(flushCallbacks);
observe.observe(textNode, {
characterData: true,
});
timerFn = () => {
textNode.textContent = 3;
};
// 微任务
} else if (setImmediate) {
timerFn = () => {
setImmediate(flushCallbacks);
};
} else {
timerFn = () => {
setTimeout(flushCallbacks);
};
}
timerFn();
}
// 微任务是在页面渲染前执行 我取的是内存中的dom,不关心你渲染完毕没有
export function nextTick(cb) {
callbacks.push(cb); // flushSchedulerQueue / userCallback
if (!waiting) {
timer(flushCallbacks); // vue2 中考虑了兼容性问题 vue3 里面不在考虑兼容性问题
waiting = true;
}
}
完 ?
下一讲,watch & computed 实现
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!