This is the second day of my participation in the August Text Challenge.More challenges in August

More articles

[vue2] Stay up late to make you understand vuE-Router and write it by hand

[vue2] Stay up late to make you understand vuex in depth and write a

[vue2] Stay up late to make you understand the V-Model principle in depth

[vue2] late night writing in order to make you easy to understand the in-depth understanding of bidirectional binding and solve the problem of listening to Array Array changes

It’s not easy to stay up late. Give it a thumbs up before you leave

concept

NextTick: Using macrotasks and microtasks, nextTick defines an asynchronous method that calls nextTick multiple times to put the method into a callback queue, and then empties the current queue using this asynchronous method

macrotask: setTimeout, setInterval, setImmediate, I/O, UI rendering

microtasks: process.nextTick, Promise, MutationObserver

The order

In the task queue, MacroTask extracts only one execution per event loop

Microtask keeps fetching until the Microsoft queue is empty

The main execution completes the task and then checks the MicroTasks queue and completes all tasks in it before executing macroTask

scenario

An operation to be performed when data changes and dom updates are required by the operation. In the Created or Mounted phase, dom updates are required after the operation

If nextTick is executed before updating the data, it will be invalid

NextTick and $nextTick:

nextTick(callback):

Global method that performs a callback when data changes and is updated

$nextTick(callback):

Instance methods, which automatically bind the context parameter to the instance that called it. When the DOM changes and is updated, the callback is typically this. $nextTick

The principle of

  1. NextTick is called with two arguments: cb, the callback function, and CTX, the context in which the callback function is executed, determines whether a callback function exists
  2. If there is, put it in the queue
  3. Return promise if no
  4. Determines whether the callback function is executing
  5. If not, the timeFunc asynchronous method is executed, and multiple executions of nextTick will only execute timerFunc once
  6. Select an asynchronous method in timeFunc:

(1) Try the Promise callback first to execute the flushCallbacks asynchronously

(2) If not, continue to try the MutationObserver callback, which creates a text node to listen on

(3) If not, continue to try the setImmediate callback and execute flushCallbacks under setImmediate

Use setTimeout(flushCallbacks, 0) to execute the flushCallbacks method

The source code

nextTick

export function nextTick (cb? : Function, ctx? : Callbacks. Push (() => {if (cb) {try {// Error cb.call(CTX)} catch (e) { handleError(e, ctx, 'nextTick') } } else if (_resolve) { _resolve(ctx) } })Copy the code
// If not currently executing, timeFunc if (! Pending) {// Flag pending = true // nextTick only executes once, timerFunc is an asynchronous method timerFunc()}}Copy the code

timeFunc

// Determine whether to support promise natively if (typeof Promise! Const p = promise.resolve () // timerFunc = () => {// timerFunc = () => {// FlushCallbacks p.hen (flushCallbacks) if (isIOS) setTimeout(noop)} // Mark isUsingMicroTask = trueCopy the code
} else if (! isIE && typeof MutationObserver ! == 'undefined' && ( isNative(MutationObserver) || MutationObserver.toString() === '[object MutationObserverConstructor]' Const observer = new MutationObserver(flushCallbacks) // Const observer = new MutationObserver(flushCallbacks Const textNode = document.createTextNode(String(counter)) // native API, Observe. observe(textNode, {characterData: }) timerFunc = () => {counter = (counter + 1) % 2Copy the code
SetImmediate} else if (typeof setImmediate! SetImmediate == 'undefined' && Mediate (setImmediate)) { Higher versions of Google also support timerFunc = () => {// Directly execute setImmediate(flushCallbacks)}Copy the code
TimerFunc = () => {setTimeout(flushCallbacks, 0)}}Copy the code

flushCallbacks

// Call queue const callbacks = [] // Let Pending = falseCopy the code
Function flushCallbacks () {pending = false const copies = callbacks.slice(0) Callbacks. Length = 0 // cb may add content to the callbacks during execution // after traversing the copied queue, new tasks will be stored in the callbacks in the next round for (let I = 0; i < copies.length; i++) { copies[i]() } }Copy the code

Question and answer

Q: What are macro and micro tasks? Do you know the Event Loop?

Recommended article: This time, thoroughly understand JavaScript execution mechanics