// nextick 实现原理
function update() {
queueWatcher(this)
}
let queue = []
let hash = {}
let pending = false
// 通过flushScheduleQueue将更新队列的watcher执行
function flushScheduleQueue() {
queue.forEach(watcher => {
watcher.run()
watcher.cb()
})
queue = []
hash = {}
pending = false
}
// 通过queueWatcher将需要批量更新的watcher存在一个队列之中,并做哈希去重操作
function queueWatcher(watcher) {
const id = watcher.id
if(hash[id] == null) {
queue.push(watcher)
hash[id] = true
if(!pending) {
nextick(flushScheduleQueue)
pending = true
}
}
}
// nextick
let cbList = []
function flushCallback() {
while(cbList.length) {
let cb = cbList.shift()
cb()
}
pending = false
}
// vue和用户都可以使用nextick
function nextick(cb) {
cbList.push(cb)
if(!pending) {
timerFunc()
pending = true
}
}
// nextick兼容处理
let timerFunc
if(Promise) {
timerFunc = () => {
Promise.resolve().then(flushCallback)
}
} else if(MutationObserver) { // 监视dom变化
let observer = new MutationObserver(flushCallback)
let textNode = document.createTextNode(1)
observer.observe(textNode, { characterData: true })
timerFunc = () => {
textNode.textContent = 2
}
} else if(setImmediate) {
timerFunc = () => {
setImmediate(flushCallback)
}
} else {
timerFunc = () => {
setTimeout(flushCallback)
}
}
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交