1

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
        })
    }
}

万年打野易大师
1.5k 声望1.1k 粉丝