共计 1129 个字符,预计需要花费 3 分钟才能阅读完成。
nextTick 在 vue 官方解释是说在下次 DOM 更新循环结束后立即执行延迟回调,获取更新后的 DOM
对于 microtasks(微任务)和 macrotasks(宏任务),vue 在 2.4 版本之前一直用 microtasks,但是它的优先级太高,在某些情况下可能会出现逼时间冒泡更快执行的情况;如果全部使用 macrotasks,对于大数据 DOM 会出现渲染性能问题。所以在新版本中 (vue 版本超过 2.4) 默认使用 microtasks,在特殊情况下会使用 macrotask,比如在使用 v -on 绑定事件。
对于使用 macrotasks,会先判断是否使用 setImmediate,不能的话降级为 MessageChannel,以上都不行,则使用 setTimeout
if(typeof setImmediate !== 'undefined' && isNative(setImmediate)) {macroTimerFunc = () => {setImmediate(flushCallbacks);
};
} else if(typeof MessageChaanel !== 'undefined' && (isNative(MessageChaanel) || MessageChaanel.toString() === '[object MessageChannelConstructor]')) {const channel = new MessageChannel();
const port = channel.port2;
channel.port1.onmessage = flushCallbacks;
macroTimerFunc = () => {port.postMessage(1);
};
} else {macroTimerFunc = () => {setTimeout(flushCallbacks, 0);
}
}
同时 nextTick 也支持 Promise
export function nextTick(cb: Function, ctx?: Object) {
let _resolve;
callbacks.push(() => {if(cb) {
try {cb.call(ctx)
} catch(e) {handleError(e, ctx, 'nextTick')
}
} else if(_resolve) {_resolve(ctx)
}
})
if(!pending) {
pending = true;
if(useMacroTask) {macroTimerFunc()
} else {microTimerFunc()
}
}
if(!cb && typeof Promise !== 'undefined') {
return new Promise(resolve => {_resolve = resolve})
}
}
正文完
发表至: javascript
2019-09-09