Table of Contents
nextTick function
Source code analysis
Capability detection
Execute the callback function queue
Implementing a simple nextTick
Home Web Front-end JS Tutorial What function does nextTick have in Vue? Simple implementation of nextTick

What function does nextTick have in Vue? Simple implementation of nextTick

Nov 24, 2018 pm 02:31 PM
nexttick

This article brings you what is the function of nextTick in Vue? How to achieve? , has certain reference value, friends in need can refer to it, I hope it will be helpful to you.

nextTick is a core function of Vue, and nextTick is often used in Vue’s internal implementation. However, many novices do not understand the principle of nextTick, or even the function of nextTick.

So, let’s first take a look at what nextTick is.

nextTick function

Look at the description of the official documentation:

Execute a delayed callback after the next DOM update cycle ends. Use this method immediately after modifying data to get the updated DOM.

Look at the official example again:

// 修改数据
vm.msg = 'Hello'
// DOM 还没有更新
Vue.nextTick(function () {
  // DOM 更新了
})

// 作为一个 Promise 使用 (2.1.0 起新增,详见接下来的提示)
Vue.nextTick()
  .then(function () {
    // DOM 更新了
  })
Copy after login

New from 2.1.0: If no callback is provided and in an environment that supports Promise, a Promise is returned. Please note that Vue does not come with Promise polyfills, so if your target browser does not natively support Promise (IE: why are you looking at me), you have to provide the polyfill yourself.

As you can see, the main function of nextTick is to change the data and let the callback function act on the dom update. Many people are confused when they see this. Why do I need to execute the callback function after the DOM is updated? After I modify the data, doesn't the DOM automatically update?

This is related to Event Loop in JS. There are countless online tutorials, so I won’t go into details here. It is recommended that you understand the Event Loop before continuing to read this article.

A practical example:

We have a table with a pager, and the first item needs to be selected every time the page is turned. Under normal circumstances, what we want is to click the page turner, obtain data from the background, update the table data, and manipulate the table API to select the first item.

However, you will find that the table data is updated, but the first item is not selected. Because when you select the first item, although the data is updated, the DOM is not updated. At this point, you can use nextTick to manipulate the selection of the first item in the table after the DOM is updated.

So, what exactly does nextTick do to execute the callback function after the DOM is updated?

Source code analysis

The source code of nextTick is located in src/core/util/next-tick.js, with a total of 118 lines. It is very short and concise, and is very suitable for students who are reading the source code for the first time.

nextTick source code is mainly divided into two parts:

1. Capability detection

2. Execute the callback queue in different ways according to the capability detection

Capability detection

This part is actually very simple. As we all know, Event Loop is divided into macro tasks and micro tasks. Regardless of whether a macro task or a micro task is executed, it will enter the next tick after completion, and will Perform UI rendering between ticks.

However, macro tasks take more time than micro tasks, so if the browser supports it, use micro tasks first. If the browser does not support microtasks, use macrotasks; however, the efficiency of various macrotasks is also different, and you need to use different macrotasks based on the browser's support.

nextTick follows this idea when it comes to ability testing.

// Determine (macro) task defer implementation.
// Technically setImmediate should be the ideal choice, but it's only available
// in IE. The only polyfill that consistently queues the callback after all DOM
// events triggered in the same loop is by using MessageChannel.
/* istanbul ignore if */
// 如果浏览器不支持Promise,使用宏任务来执行nextTick回调函数队列
// 能力检测,测试浏览器是否支持原生的setImmediate(setImmediate只在IE中有效)
if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
  // 如果支持,宏任务( macro task)使用setImmediate
  macroTimerFunc = () => {
    setImmediate(flushCallbacks)
  }
  // 同上
} else if (typeof MessageChannel !== 'undefined' && (
  isNative(MessageChannel) ||
  // PhantomJS
  MessageChannel.toString() === '[object MessageChannelConstructor]'
)) {
  const channel = new MessageChannel()
  const port = channel.port2
  channel.port1.onmessage = flushCallbacks
  macroTimerFunc = () => {
    port.postMessage(1)
  }
} else {
  /* istanbul ignore next */
  // 都不支持的情况下,使用setTimeout
  macroTimerFunc = () => {
    setTimeout(flushCallbacks, 0)
  }
}
Copy after login

First, check whether the browser supports setImmediate. If not, use MessageChannel. If not, you can only use setTimeout, which is the least efficient but the most compatible.

After that, check whether the browser supports Promise. If it does, use Promise to execute the callback function queue. After all, microtasks are faster than macrotasks. If it is not supported, you can only use macro tasks to execute the callback function queue.

Execute the callback function queue

The code for executing the callback function queue is just at the beginning and the end

// 回调函数队列
const callbacks = []
// 异步锁
let pending = false

// 执行回调函数
function flushCallbacks () {
  // 重置异步锁
  pending = false
  // 防止出现nextTick中包含nextTick时出现问题,在执行回调函数队列前,提前复制备份,清空回调函数队列
  const copies = callbacks.slice(0)
  callbacks.length = 0
  // 执行回调函数队列
  for (let i = 0; i < copies.length; i++) {
    copies[i]()
  }
}

...

// 我们调用的nextTick函数
export function nextTick (cb?: Function, ctx?: Object) {
  let _resolve
  // 将回调函数推入回调队列
  callbacks.push(() => {
    if (cb) {
      try {
        cb.call(ctx)
      } catch (e) {
        handleError(e, ctx, &#39;nextTick&#39;)
      }
    } else if (_resolve) {
      _resolve(ctx)
    }
  })
  // 如果异步锁未锁上,锁上异步锁,调用异步函数,准备等同步函数执行完后,就开始执行回调函数队列
  if (!pending) {
    pending = true
    if (useMacroTask) {
      macroTimerFunc()
    } else {
      microTimerFunc()
    }
  }
  // $flow-disable-line
  // 2.1.0新增,如果没有提供回调,并且支持Promise,返回一个Promise
  if (!cb && typeof Promise !== &#39;undefined&#39;) {
    return new Promise(resolve => {
      _resolve = resolve
    })
  }
}
Copy after login

The overall process is to receive the callback function and push the callback function into the callback function queue middle.

At the same time, when receiving the first callback function, execute the corresponding asynchronous method in the capability test (the callback function queue is called in the asynchronous method).

How to ensure that the asynchronous method is only executed when the first callback function is received?

nextTick source code uses the concept of an asynchronous lock, that is, when receiving the first callback function, first close the lock and execute the asynchronous method. At this time, the browser is waiting for the synchronous code to be executed before executing the asynchronous code.

An analogy: It is equivalent to a group of passengers preparing to get on the bus. When the first passenger gets on the bus, the bus starts to start and is ready to go. After all passengers get on the bus, you can officially start driving.

Of course, there is a difficult point to understand when executing the flushCallbacks function, namely: why do you need to back up the callback function queue? Is the callback function queue also executed?

Because, there will be such a situation: nextTick applies nextTick. If flushCallbacks does not perform special processing and directly executes the callback function in a loop, the callback function in nextTick will enter the callback queue. This is equivalent to passengers on the next bus boarding the previous bus.

Implementing a simple nextTick

Having said so much, let’s implement a simple nextTick:

let callbacks = []
let pending = false

function nextTick (cb) {
    callbacks.push(cb)

    if (!pending) {
        pending = true
        setTimeout(flushCallback, 0)
    }
}

function flushCallback () {
    pending = false
    let copies = callbacks.slice()
    callbacks.length = 0
    copies.forEach(copy => {
        copy()
    })
}
Copy after login

As you can see, in the simple version of nextTick, through nextTick Receive the callback function and execute the callback function asynchronously through setTimeout. In this way, the callback function can be executed in the next tick, that is, the callback function is executed after the UI is re-rendered.

The above is the detailed content of What function does nextTick have in Vue? Simple implementation of nextTick. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What should I do if I encounter garbled code printing for front-end thermal paper receipts? What should I do if I encounter garbled code printing for front-end thermal paper receipts? Apr 04, 2025 pm 02:42 PM

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

Who gets paid more Python or JavaScript? Who gets paid more Python or JavaScript? Apr 04, 2025 am 12:09 AM

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

How to merge array elements with the same ID into one object using JavaScript? How to merge array elements with the same ID into one object using JavaScript? Apr 04, 2025 pm 05:09 PM

How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

The difference in console.log output result: Why are the two calls different? The difference in console.log output result: Why are the two calls different? Apr 04, 2025 pm 05:12 PM

In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...

TypeScript for Beginners, Part 2: Basic Data Types TypeScript for Beginners, Part 2: Basic Data Types Mar 19, 2025 am 09:10 AM

Once you have mastered the entry-level TypeScript tutorial, you should be able to write your own code in an IDE that supports TypeScript and compile it into JavaScript. This tutorial will dive into various data types in TypeScript. JavaScript has seven data types: Null, Undefined, Boolean, Number, String, Symbol (introduced by ES6) and Object. TypeScript defines more types on this basis, and this tutorial will cover all of them in detail. Null data type Like JavaScript, null in TypeScript

How to achieve parallax scrolling and element animation effects, like Shiseido's official website?
or:
How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? How to achieve parallax scrolling and element animation effects, like Shiseido's official website? or: How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? Apr 04, 2025 pm 05:36 PM

Discussion on the realization of parallax scrolling and element animation effects in this article will explore how to achieve similar to Shiseido official website (https://www.shiseido.co.jp/sb/wonderland/)...

Can PowerPoint run JavaScript? Can PowerPoint run JavaScript? Apr 01, 2025 pm 05:17 PM

JavaScript can be run in PowerPoint, and can be implemented by calling external JavaScript files or embedding HTML files through VBA. 1. To use VBA to call JavaScript files, you need to enable macros and have VBA programming knowledge. 2. Embed HTML files containing JavaScript, which are simple and easy to use but are subject to security restrictions. Advantages include extended functions and flexibility, while disadvantages involve security, compatibility and complexity. In practice, attention should be paid to security, compatibility, performance and user experience.

See all articles