Jadual Kandungan
模块变量
异步延迟函数
Rumah hujung hadapan web tutorial js Vue2.6中的nextTick方法分析

Vue2.6中的nextTick方法分析

Feb 28, 2019 am 11:58 AM
javascript vue.js

本篇文章给大家带来的内容是关于Vue2.6中的nextTick方法分析),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

浅析 Vue 2.6 中的 nextTick 方法。

事件循环

JS 的 事件循环任务队列 其实是理解 nextTick 概念的关键。
这个网上其实有很多优质的文章做了详细介绍,我就简单过过了。

以下内容适用于浏览器端 JS,NodeJS 的事件循环机制并不相同。

规范中规定 task 分为两大类: task(macrotask)microtask

通常认为是 task 的任务源:

setTimeout / setInterval
setImmediate
MessageChannel
I/O
UI rendering
Salin selepas log masuk

通常认为是 microtask 的任务源:

Promise
process.nextTick
MutationObserver
Object.observe(已废弃)
Salin selepas log masuk

简单概况:(这里是官方规范)

  1. 首先开始执行 script 脚本,直到执行上下文栈为空时,开始清空 microtask 队列里的任务,队列嘛,先入先出,出一个执行一个,清空完毕,走事件循环。

  2. 事件循环:不断地去取 task 队列的中的一个任务推入栈中执行,并在当次循环里依次清空 microtask 队列里的任务,清空之后,可能会触发页面更新渲染(由浏览器决定)。

  3. 之后重复 事件循环 步骤。

nextTick

Vue 中数据的变化到 DOM 的更新渲染是一个异步过程。
此方法便用于在 DOM 更新循环结束之后执行延迟回调。
使用方法很简单:

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

// 作为一个 Promise 使用
Vue.nextTick().then(function() {
  // DOM 更新了
});
Salin selepas log masuk

源码 去除注释,其实也只有不到一百来行,整体还是很容易理解的。

这里划成 3 个部分介绍。

模块变量

介绍 引入的模块 和 定义的变量。

// noop 空函数,可用作函数占位符
import { noop } from 'shared/util';

// Vue 内部的错误处理函数
import { handleError } from './error';

// 判断是IE/IOS/内置函数
import { isIE, isIOS, isNative } from './env';

// 使用 MicroTask 的标识符
export let isUsingMicroTask = false;

// 以数组形式存储执行的函数
const callbacks = [];

// nextTick 执行状态
let pending = false;

// 遍历函数数组执行每一项函数
function flushCallbacks() {
  pending = false;
  const copies = callbacks.slice(0);
  callbacks.length = 0;
  for (let i = 0; i < copies.length; i++) {
    copies[i]();
  }
}
Salin selepas log masuk

异步延迟函数

接下来是核心的 异步延迟函数。这里不同的 Vue 版本采用的策略其实并不相同。

2.6 版本优先使用 microtask 作为异步延迟包装器。

2.5 版本则是 macrotask 结合 microtask。然而,在重绘之前状态改变时会有小问题(如 #6813)。此外,在事件处理程序中使用 macrotask 会导致一些无法规避的奇怪行为(如#7109,#7153,#7546,#7834,#8109)。

所以 2.6 版本现在又改用 microtask 了,为什么是又呢。。因为 2.4 版本及之前也是用的 microtask。。。

microtask 在某些情况下也是会有问题的,因为 microtask 优先级比较高,事件会在顺序事件(如#4521,#6690 有变通方法)之间甚至在同一事件的冒泡过程中触发(#6566)。

// 核心的异步延迟函数,用于异步延迟调用 flushCallbacks 函数
let timerFunc;

// timerFunc 优先使用原生 Promise
// 原本 MutationObserver 支持更广,但在 iOS >= 9.3.3 的 UIWebView 中,触摸事件处理程序中触发会产生严重错误
if (typeof Promise !== 'undefined' && isNative(Promise)) {
  const p = Promise.resolve();
  timerFunc = () => {
    p.then(flushCallbacks);

    // IOS 的 UIWebView,Promise.then 回调被推入 microtask 队列但是队列可能不会如期执行。
    // 因此,添加一个空计时器“强制”执行 microtask 队列。
    if (isIOS) setTimeout(noop);
  };
  isUsingMicroTask = true;

  // 当原生 Promise 不可用时,timerFunc 使用原生 MutationObserver
  // 如 PhantomJS,iOS7,Android 4.4
  // issue #6466 MutationObserver 在 IE11 并不可靠,所以这里排除了 IE
} else if (
  !isIE &&
  typeof MutationObserver !== 'undefined' &&
  (isNative(MutationObserver) ||
    // PhantomJS 和 iOS 7.x
    MutationObserver.toString() === '[object MutationObserverConstructor]')
) {
  let counter = 1;
  const observer = new MutationObserver(flushCallbacks);
  const textNode = document.createTextNode(String(counter));
  observer.observe(textNode, {
    characterData: true,
  });
  timerFunc = () => {
    counter = (counter + 1) % 2;
    textNode.data = String(counter);
  };
  isUsingMicroTask = true;

  // 如果原生 setImmediate 可用,timerFunc 使用原生 setImmediate
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
  timerFunc = () => {
    setImmediate(flushCallbacks);
  };
} else {
  // 最后的倔强,timerFunc 使用 setTimeout
  timerFunc = () => {
    setTimeout(flushCallbacks, 0);
  };
}
Salin selepas log masuk

一句话总结优先级:microtask 优先
Promise > MutationObserver > setImmediate > setTimeout

nextTick 函数

nextTick 函数。接受两个参数:

  1. cb 回调函数:是要延迟执行的函数;

  2. ctx:指定 cb 回调函数 的 this 指向

Vue 实例方法 $nextTick 做了进一步封装,把 ctx 设置为当前 Vue 实例

export function nextTick(cb?: Function, ctx?: Object) {
  let _resolve;

  // cb 回调函数会经统一处理压入 callbacks 数组
  callbacks.push(() => {
    if (cb) {
      // 给 cb 回调函数执行加上了 try-catch 错误处理
      try {
        cb.call(ctx);
      } catch (e) {
        handleError(e, ctx, 'nextTick');
      }
    } else if (_resolve) {
      _resolve(ctx);
    }
  });

  // 执行异步延迟函数 timerFunc
  if (!pending) {
    pending = true;
    timerFunc();
  }

  // 当 nextTick 没有传入函数参数的时候,返回一个 Promise 化的调用
  if (!cb && typeof Promise !== 'undefined') {
    return new Promise(resolve => {
      _resolve = resolve;
    });
  }
}
Salin selepas log masuk

小结

整体看过来,感觉还是比较好理解的吧~ 2.6 版本相比之前简化了一点。

小结一下,每次调用 Vue.nextTick(cb) 会做些什么:
cb 函数经处理压入 callbacks 数组,执行 timerFunc 函数,延迟调用 flushCallbacks 函数,遍历执行 callbacks 数组中的所有函数。

延迟调用优先级如下:
Promise > MutationObserver > setImmediate > setTimeout

版本差异

其实 Vue 2.4、2.5、2.6 版本的 nextTick 策略都略不一样。

整体 2.62.4 的比较相似。(仔细瞅了瞅,基本就是一样的,2.6 timerFunc 多了个 setImmediate 判断)

2.5 版本其实也差不多。。。源码写法有些不一样,整体优先级是:Promise > setImmediate > MessageChannel > setTimeout,如果更新是在 v-on 事件处理程序中触发的,nextTick 会优先使用 macrotask。

Atas ialah kandungan terperinci Vue2.6中的nextTick方法分析. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 pm 02:54 PM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata Dec 17, 2023 pm 05:30 PM

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata Cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata Dec 17, 2023 pm 12:09 PM

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Bagaimana untuk melaksanakan sistem tempahan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem tempahan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 am 09:39 AM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Dec 17, 2023 pm 05:13 PM

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Jan 05, 2024 pm 06:08 PM

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Bagaimana untuk menggunakan insertBefore dalam javascript Bagaimana untuk menggunakan insertBefore dalam javascript Nov 24, 2023 am 11:56 AM

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).

Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Jan 05, 2024 pm 01:37 PM

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut

See all articles