nextTick 原理
- 让一批方法异步的批量处理
- 原理:将异步需要执行的fn放到数组中,在微任务或宏任务里统一遍历执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var fnArr = [];
var flag = false;
function nextTick(fn) {
fnArr.push(fn);
if(!flag) {
flag = true; // Promise只需要执行一次即可,由于then属于微任务,等then开始执行时,fnArr已收集完毕
Promise.resolve().then(() => {
fnArr.forEach(fn => fn());
});
}
}
function render() {
console.log('render...');
}
nextTick(render);
nextTick(render);
nextTick(render);
console.log('sync...');
</script>
</body>
</html>
引自
核心答案:
nextTick中的回调是在下次 DOM 更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。原理就是异步方法(promise,mutationObserver,setImmediate,setTimeout)经常与事件环一起来问(宏任务和微任务)
#补充回答:
vue多次更新数据,最终会进行批处理更新。内部调用的就是nextTick实现了延迟更新,用户自定义的nextTick中的回调会被延迟到更新完成后调用,从而可以获取更新后的DOM。
#快速Mock:
let cbs = [];
let pending = false;
function flushCallbacks() {
cbs.forEach(fn=>fn());
}
function nextTick(fn) {
cbs.push(fn);
if (!pending) {
pending = true;
setTimeout(() => {
flushCallbacks();
}, 0);
}
}
function render() {
console.log('rerender');
};
nextTick(render)
nextTick(render)
nextTick(render);
console.log('sync...')
源码位置:
src/core/global-api/mixin:5
、src/core/util/next-tick.js:87
网友评论