Introduction to Vue. nextTick and vue. nexttick

Source: Internet
Author: User

Introduction to Vue. nextTick and vue. nexttick

This is the source code parsing implemented by the vue. nextTick API after event loop and MicroTask.

Push, write a sleep function

function sleep (ms) { return new Promise(resolve => setTimeout(resolve, ms)}async function oneTick (ms) { console.log('start') await sleep(ms) console.log('end')}oneTick(3000)

Explain the sleep function

When the async function is running await PromiseFn (), the function execution is paused. We also know that the PromiseFn is executed in the microTask. When the microTask is not completed, the macroTask will not be executed. We also implement a sleep function through the features of the microTask in event loop, blocking the execution of console. log.

Process

1. Run console. log ('start ')
2. The await execution is paused. Wait until the execution of the PromiseFn after the await function is completed in the microTask.
3. In the sleep function, the latency is returned by ms.
4. After returning the resolve, run console. log ('end ')

NextTick API

How to Use nextTick in vue

vue.nextTick(() => { // todo...})

After understanding the usage, check the source code.

Const nextTick = (function () {const callbacks = [] let pending = false let timerFunc // scheduled function nextTickHandler () {pending = false const copies = callbacks. slice (0) // copy callbacks. length = 0 // clear for (let I = 0; I <copies. length; I ++) {copies [I] () // run one by one} if (typeof Promise! = 'Undefined' & isNative (Promise) {var p = Promise. resolve () var logError = err => {console. error (err)} timerFunc = () => {p. then (nextTickHandler ). catch (logError) // key} else if ('! IsIE MutationObserver ') {var counter = 1 var observer = new MutationObserver (nextTickHandler) // key var textNode = document. createTextNode (string (conter) observer. observe (textNode, {characterData: true}) timerFunc = () => {counter = (counter + 1) % 2 textNode. data = String (counter)} else {timerFunc = () => {setTimeout (nextTickHandler, 0) // key} return function queueNextTick (cb, ctx ){ // Api usage let _ resolve callbacks. push () => {if (cb) {try {cb. call (ctx)} catch (e) {err} else if (_ resolve) {_ resolve (ctx)} if (! Pending) {pending = true timerFunc ()} if (! Cb & typeof Promise! = 'Undefined') {return new Promise (resolve, reject) =>{_ resolve = resolve}) }}) () // self-executed Function

Let's take a rough look at the source code. We can see that nextTick api is a self-executed function.

Since it is a self-executed function, let's look at its return type directly. return function queueNextTick (cb, ctx ){...}

Return function queueNextTick (cb, ctx) {// api usage let _ resolve callbacks. push () => {if (cb) {try {cb. call (ctx)} catch (e) {err} else if (_ resolve) {_ resolve (ctx)} if (! Pending) {pending = true timerFunc ()} if (! Cb & typeof Promise! = 'Undefined') {return new Promise (resolve, reject) =>{_ resolve = resolve })}}

Only focus on the main process. The queueNextTick function pushes the passed () =>{// todo...} into callbacks.

If (typeof Promise! = 'Undefined' & isNative (Promise) {var p = Promise. resolve () var logError = err => {console. error (err)} timerFunc = () => {p. then (nextTickHandler ). catch (logError) // key} else if ('! IsIE MutationObserver ') {var counter = 1 var observer = new MutationObserver (nextTickHandler) // key var textNode = document. createTextNode (string (conter) observer. observe (textNode, {characterData: true}) timerFunc = () => {counter = (counter + 1) % 2 textNode. data = String (counter)} else {timerFunc = () => {setTimeout (nextTickHandler, 0) // key }}

In this section, we can see that the three points marked indicate that the nextTickHandler is executed using Promise, MutationObserver or setTimeout (fn, 0) in different browser environments.

Function nextTickHandler () {pending = false const copies = callbacks. slice (0) // copy callbacks. length = 0 // clear for (let I = 0; I <copies. length; I ++) {copies [I] () // execute one by one }}

NextTickHandler is to put the previously put callbacks () =>{// todo...} in the current tasks for execution.

Write a simple nextTick

The source code may be different. Let's write a simple nextTick.

Const simpleNextTick = (function () {let callbacks = [] let timerFunc return function queueNextTick (cb) {callbacks. push () =>{// push cb ()}) timerFunc = () =>{ return Promise to callbacks. resolve (). then () => {const fn = callbacks. shift () fn ()} timerFunc () // executes timerFunc and returns a Promise}) () simpleNextTick () => {setTimeout (console. log, 3000, 'nexttick ')})

We can see from here that the principle of nextTick is to return a Promise, and our todo code is executed in this Promise. Now we can continue to simplify it.

const simpleNextTick = (function () { return function queueNextTick (cb) {  timerFunc = () => {   return Promise.resolve().then(() => {    cb()   })  }  timerFunc() }})()simpleNextTick(() => { setTimeout(console.log, 3000, 'nextTick')})

Write it as follows.

const simpleNextTick = function queueNextTick (cb) {  timerFunc = () => {   return Promise.resolve().then(() => {    cb()   })  }  timerFunc() }simpleNextTick(() => { setTimeout(console.log, 3000, 'nextTick')})

This time, we simplified the self-executed function.

const simpleNextTick = function queueNextTick (cb) {   return Promise.resolve().then(cb) }simpleNextTick(() => { setTimeout(console.log, 3000, 'nextTick')})

Now we can directly simplify it to the end. Now we find that the core content of nextTick is Promise, a microtask.

Now let's go back to the official nextTick API example of vue.

<Div id = "example" >{{ message }}</div> var vm = new Vue ({el: '# example', data: {message: '200'}) vm. message = 'new message' // change the vm. $ el. textContent = 'new message' // falseVue. nextTick (function () {vm. $ el. textContent = 'new message' // true })

After the data in the vue is updated, dom update is executed after the next event loop.
NextTick's usage principle is mainly to solve the scenario of operating dom immediately after a single event updates data.

Now that we know that the core of nextTick is to use microTasks, we can compare the simplified nextTick with the sleep function at the beginning.

Const simpleNextTick = function queueNextTick (cb) {return Promise. resolve (). then (cb)} simpleNextTick () => {setTimeout (console. log, 3000, 'nexttick') // you can change it to an ajax request })
Function sleep (MS) {return new Promise (resolve => setTimeout (resolve, MS) // you can also change to ajax request} async function oneTick (MS) {console. log ('start') await sleep (MS) console. log ('end')} oneTick (0, 3000)

We can see that the execution results of nextTick and oneTick written by me are so similar. The difference is that nextTick returns and executes the callback package a Promise, while oneTick uses await to execute a Promise function, and this Promise has its own webapi function.

When ajax requests are used, can we directly use axios to return the Promise library?

Async function getData () {const data = await axios. get (url) // manipulate data to change dom return data}

This can also achieve the same effect as nextTick.

Finally, we can also see from the source code that when the browser environment does not support Promise, you can use MutationObserver or setTimeout (cb, 0) to achieve the same effect. However, the final core is microTask.

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.