我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Vue2异步更新及nextTick原理是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Vue2异步更新及nextTick原理是什么

这篇文章主要介绍“Vue2异步更新及nextTick原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue2异步更新及nextTick原理是什么”文章能帮助大家解决问题。

JavaScript 执行机制

浏览器是多线程的,例如GUI渲染线程、JS引擎线程、事件监听线程等。

javascript 执行机制就是借用浏览器的多线程机制,再基于 Event Loop 事件循环机制实现的。其实现了单线程异步效果

Event Loop 步骤大致如下:

浏览器加载页面时,除了开辟堆栈内存外,还会创建两个队列 Web API:任务监听队列,监测异步任务是否可以执行 Task Queue:任务队列,分为异步宏任务队列和异步微任务队列 当主线程自上而下执行代码过程中,如果遇到异步代码,则把异步任务放到 Web API 中去监听 浏览器会开辟新的线程去监听是否可以执行 不会阻碍主线程的渲染,它会继续向下执行同步代码 当异步任务被监测为可以执行了(有了运行结果),也不会立即去执行,而是在 task queue 中放置一个事件,排队等待执行 根据微任务还是宏任务,放在不同的队列中 谁先进来排队的,谁在各自队伍的最前面 执行栈中的所有同步任务执行完毕,主线程空闲下来,此时会去 task queue 中把正在排队的事件,按照顺序取出来,进入主线程执行 微任务优先级比较高。当执行栈为空时,先去执行微任务队列中的事件,直到微任务队列为空,才会去执行宏任务队列中的事件 上述过程会不断重复,也就是常说的事件循环(Event Loop)

task 又分为宏任务(macro task)和微任务(micro task)两大类,在浏览器环境中

常见的 macro task 有 script(整体代码)、setTimeout/setInterval/setImmediateXMLHttpRequest/fetch,DOM事件(如鼠标点击、滚动页面、放大缩小等),渲染事件(解析 DOM、计算布局、绘制) 常见的 micro task 有 Promise.then/catch/finallyasync/awaitMutationObserver

需要注意的是!!!如果处理微任务的过程中有新的微任务添加进来了,添加的速度一直比执行快,则永远执行微任务

下面的代码永远不会打印宏任务输出

function macroFn(){   setTimeout(() => {     console.log('>>>>MA')   },0)}function microFn(){    Promise.resolve().then(() => {        console.log('mi')        microFn()    })}macroFn()microFn()

nextTick实现原理

vue2.7 源码中,有一个单独的文件class="lazy" data-src/core/util/next-tick.js去维护 nextTick,有兴趣的同学可以自行去观看

vue2.7 源码中,nextTick并没有直接使用某个 API ,而是采用了优雅降级的方案去实现异步更新

在内部会尝试使用原生的Promise.then (IE不支持)MutationObserversetImmediate (高版本IE专享),如果执行环境还不支持的话,则会采用 setTimeout(fn, 0)

需要注意的是,我们维护了一个 callbacks,用于存储 nextTick 回调

这样就保证了在同一个 tick 内多次调用 nextTick,只需创建一个异步任务,就可以依次执行 callbacks 中的所有 nextTick 回调。而不是去开启多个异步任务去处理。

let callbacks = [] // 存储 nextTick 回调let waiting = false // 防抖// 按照顺序依次执行 callbacks 中的方法function flushCallbacks() {  let cbs = callbacks.slice(0)  waiting = false  callbacks = []  cbs.forEach(cb => cb()) }let timerFunc;if (Promise) {    timerFunc = () => {        Promise.resolve().then(flushCallbacks)    }}else if(MutationObserver){    let observer = new MutationObserver(flushCallbacks); // 这里传入的回调是异步执行的    let textNode = document.createTextNode(1);    observer.observe(textNode,{        characterData:true    });    timerFunc = () => {        textNode.textContent = 2;    }}else if(setImmediate){    timerFunc = () => {       setImmediate(flushCallbacks);    }}else{    timerFunc = () => {        setTimeout(flushCallbacks);     }}export function nextTick(cb) {  callbacks.push(cb) // 维护 nextTick 中的 cakllback 方法    if (!waiting) {    timerFunc()    waiting = true  }}

异步更新

vue 内部的异步更新渲染也使用了 nextTick

在 Watcher 类的 update 更新方法中,我们调用了 queueWatcher 异步队列更新方法,该方法在 vue2.7源码中的 class="lazy" data-src/core/util/scheduler.js 文件中维护

import { queueWatcher } from './scheduler'class Watcher {...  // 重新渲染  update() {    console.log('watcher-update')    queueWatcher(this) // watcher 异步更新  }}

class="lazy" data-src/core/util/scheduler.js

import { nextTick } from '../util/next-tick'let queue = []let has = {}let pending = false // 防抖function flushSchedulerQueue() {  let flushQueue = queue.slice(0)  queue = []  has = {}  pending = false  flushQueue.forEach(q => q.run()) // 在刷新的过程中可能还有新的 watcher,重新放到 queue 中}// 在一个tick周期内,不管我们的 update 执行多少次,只会执行一轮刷新操作export function queueWatcher(watcher) {  const id = watcher.id  if (!has[id]) {    queue.push(watcher)    has[id] = true    if (!pending) {      nextTick(flushSchedulerQueue)      pending = true    }  }}

常见问题

nexTick 是异步还是同步?

这个不能一概而论,nextTick 内部既有同步代码又有异步代码。

例如 维护 callbacks 队列是同步任务;执行队列中的方法是异步任务

nextTick 回调的执行是微任务还是宏任务?

针对 vue2.7 来说,nextTick并没有直接使用某个 API ,而是采用了优雅降级的方案去实现异步更新。
在内部会尝试使用原生的Promise.then (微任务)MutationObserver (微任务)setImmediate (宏任务),如果执行环境还不支持的话,则会采用 setTimeout (宏任务)

可以理解为 99% 的场景下都是微任务,只有在不支持 Promise 和 MutationObserver API的浏览器中,才会是宏任务,例如 IE9 、IE10

为什么要封装 nextTick?而不是使用某个具体的 API?

优雅降级。尽量使用微任务,尽可能缩短渲染周期

保证统一性。nextTick 可以暴露给用户,保证用户在修改数据之后立即使用这个方法,可以获取更新后的 DOM

this.name = 'libc'this.$nextTick(()=>{  console.log(document.querySelector('.user').innerHTML)});

关于“Vue2异步更新及nextTick原理是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Vue2异步更新及nextTick原理是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Vue2异步更新及nextTick原理是什么

这篇文章主要介绍“Vue2异步更新及nextTick原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue2异步更新及nextTick原理是什么”文章能帮助大家解决问题。JavaScript
2023-07-05

Vue2异步更新及nextTick原理详解

Vue2的异步更新机制是基于JavaScript的事件循环机制实现的。nextTick方法则是在DOM更新后执行回调函数。本文详细介绍了Vue2的异步更新机制和nextTick原理,对于理解Vue2的渲染机制和优化性能有很大的帮助。
2023-05-15

Vue异步更新机制及$nextTick原理是什么

本文小编为大家详细介绍“Vue异步更新机制及$nextTick原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue异步更新机制及$nextTick原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧
2023-06-30

Vue3组件异步更新和nextTick运行机制是什么

这篇文章主要讲解了“Vue3组件异步更新和nextTick运行机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue3组件异步更新和nextTick运行机制是什么”吧!组件的异步更新
2023-07-06

Vue异步更新机制和nextTick原理实例分析

这篇文章主要介绍“Vue异步更新机制和nextTick原理实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue异步更新机制和nextTick原理实例分析”文章能帮助大家解决问题。1. 异步更
2023-06-27

在vue中nextTick用法及nextTick的原理是什么

这篇文章主要介绍了在vue中nextTick用法及nextTick的原理是什么,Vue.js是一个流行的前端框架,它提供了一种响应式的数据绑定机制,使得页面的数据与页面的UI组件之间能够自动同步,需要的朋友可以参考下
2023-05-16

vue的异步数据更新机制与$nextTick使用方法是什么

这篇文章主要讲解了“vue的异步数据更新机制与$nextTick使用方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue的异步数据更新机制与$nextTick使用方法是什么”吧!v
2023-07-05

React setState异步原理是什么

本文小编为大家详细介绍“React setState异步原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“React setState异步原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。setSt
2023-07-04

unity异步加载原理是什么

Unity的异步加载原理是利用协程(Coroutine)和异步操作(AsyncOperation)来实现的。在Unity中,协程是一种特殊的函数,可以在执行到一定点时暂停,并在后续某个时刻继续执行。协程可以通过使用yield return语
2023-09-29

dubbo异步调用的原理是什么

Dubbo异步调用的原理是通过使用线程池来实现异步调用。首先,服务消费者发送请求给服务提供者,然后服务提供者将请求放入线程池中进行处理。线程池中的线程会并发地执行请求,并且不会阻塞服务提供者的主线程。一旦线程处理完请求,就会返回给服务消费者
2023-10-23

C#中异步调用的原理是什么

本篇文章为大家展示了C#中异步调用的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。C#异步调用是什么呢?具体的内容又是什么呢?让我们开始C#异步调用的学习吧计算机中有些处理比较耗时。调用这
2023-06-17

ADO.NET 批处理更新步骤是什么

本篇内容介绍了“ADO.NET 批处理更新步骤是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在ADO.NET 批处理中,批处理更新只可
2023-06-17

Java缓存更新的原理是什么

这篇文章主要介绍“Java缓存更新的原理是什么”,在日常操作中,相信很多人在Java缓存更新的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java缓存更新的原理是什么”的疑惑有所帮助!接下来,请跟
2023-06-04

sql批量更新的原理是什么

批量更新是指一次性更新多条记录,而不是逐条更新。在SQL中,可以使用UPDATE语句来实现批量更新操作。其原理是将一组更新操作合并为一个事务,减少数据库的交互次数,提高更新效率。当执行批量更新操作时,数据库系统会将多个更新语句打包在一起,
sql批量更新的原理是什么
2024-03-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录