Analysis of nextTick principle of vue

Keywords: Javascript Vue

nextTick's official explanation in vue is to perform a delayed callback immediately after the end of the next DOM update cycle to retrieve the updated DOM.

For microtasks (micro tasks) and macrotasks (macrotasks), Vue has been using microtasks until version 2.4, but its priority is too high. In some cases, it may occur to make time bubbles faster to execute; if all macrotasks are used, there will be rendering performance problems for large data DOM. So in the new version (vue version more than 2.4), microtasks are used by default, and macrotasks are used in special cases, such as using v-on binding events.

For macrotasks, you will first decide whether to use setImmediate or not, and if not, downgrade to MessageChannel. If none of the above is possible, you will use 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 also supports 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
        })
    }
}

Posted by leocon on Fri, 04 Oct 2019 01:15:29 -0700