Vue任务调度。

vue,任务调度 · 浏览次数 : 10

小编点评

1、**作用**:作用vue中一个非常重要的功能,批量更新或者叫异步更新响应式数据发生变化出发副作用函数重新执行时,我们可以去决定副作用函数的执行时机、次数和方式。 2、**例子**: ```js const state = reactive({ num: 1})effect(() => { console.log('num', state.num)})state.num++console.log('end') ``` **实现**:通过scheduler函数来实现延迟的副作用函数执行。 3、**实现可调度**:使用scheduler函数包裹副作用函数,并在副作用函数的执行前后设置标志变量。 4、**批量更新 & 异步更新**: - **num的每次变化都会导致scheduler的执行,并将注册好的副作用函数存入jobQueue队列。** - **当num被更改100次之后同步代码全部执行结束后,then回调将会被执行,此时num已经是101,而jobQueue中也只有一个fn,所以最终只会打印一次101。**

正文

1、作用

vue中一个非常重要的功能,批量更新或者叫异步更新
响应式数据发生变化出发副作用函数重新执行时,我们有能力去决定副作用函数的执行时机、次数和方式。

2、例子

const state = reactive({
  num: 1
})

effect(() => {
  console.log('num', state.num)
})

state.num++

console.log('end')

image

3、实现可调度

const state = reactive({
  num: 1
})

effect(() => {
  console.log(state.num)
}, {
  // 注意这里,假如num发生变化的时候执行的是scheduler函数
  // 那么end将会被先执行,因为我们用setTimeout包裹了一层fn
  scheduler (fn) {
    // 异步执行
    setTimeout(() => {
      fn()
    }, 0)
  }
})

state.num++

console.log('end')

通过scheduler来自主控制副作用函数的执行时机。
在这之前,执行state.num++之后,console.log(state.num)将会被马上执行,而添加scheduler后,num发生变化后将执行scheduler中的逻辑。

4、实现批量更新 & 异步更新

来看段诡异的代码,请问num会被执行多少次?100还是101?

const state = reactive({
  num: 1
})

effect(() => {
  console.log('num', state.num)
})

let count = 100

while (count--) {
  state.num++
}

image
对于页面渲染来说1到101中间的2~100仅仅只是过程,并不是最终的结果,处于性能考虑Vue只会渲染最后一次的101。

Vue是如何做到的呢?

利用可调度性,再加点事件循环的知识,我们就可以做到这件事。

  • num的每次变化都会导致scheduler的执行,并将注册好的副作用函数存入jobQueue队列,因为Set本身的去重性质,最终只会存在一个fn
  • 利用Promise微任务的特性,当num被更改100次之后同步代码全部执行结束后,then回调将会被执行,此时num已经是101,而jobQueue中也只有一个fn,所以最终只会打印一次101
 const state = reactive({
  num: 1
})

const jobQueue = new Set()
const p = Promise.resolve()
let isFlushing = false

const flushJob = () => {
  if (isFlushing) {
    return
  }

  isFlushing = true
  // 微任务
  p.then(() => {
    jobQueue.forEach((job) => job())
  }).finally(() => {
    // 结束后充值设置为false
    isFlushing = false
  })
}

effect(() => {
  console.log('num', state.num)
}, {
  scheduler (fn) {
    // 每次数据发生变化都往队列中添加副作用函数
    jobQueue.add(fn)
    // 并尝试刷新job,但是一个微任务只会在事件循环中执行一次,所以哪怕num变化了100次,最后也只会执行一次副作用函数
    flushJob()
  }
})

let count = 100

while (count--) {
  state.num++
}

image

与Vue任务调度。相似的内容:

Vue任务调度。

### 1、作用 vue中一个非常重要的功能,批量更新或者叫异步更新 响应式数据发生变化出发副作用函数重新执行时,我们有能力去决定副作用函数的执行时机、次数和方式。 ### 2、例子 ```javascript const state = reactive({ num: 1 }) effect(()

VUE系列之性能优化--懒加载

一、懒加载的基本概念 懒加载是一种按需加载技术,即在用户需要时才加载相应的资源,而不是在页面初始加载时一次性加载所有资源。这样可以减少页面初始加载的资源量,提高页面加载速度和用户体验。 二、Vue 中的懒加载 在 Vue.js 中,懒加载主要用于路由组件的按需加载。Vue Router 提供了非常便

深入理解 Vue 3 组件通信

在 Vue 3 中,组件通信是一个关键的概念,它允许我们在组件之间传递数据和事件。本文将介绍几种常见的 Vue 3 组件通信方法,包括 props、emits、provide 和 inject、事件总线以及 Vuex 状态管理。 1. 使用 props 和 emits 进行父子组件通信 props

Vue 3 后端错误消息处理范例

前端如何存储处理后端返回的错误信息,并按不同来源绑定到页面,例如显示在不同输入框的周围。这样即可实现清晰的错误显示。

Vue - 入门

零:前端目前形势 前端的发展史 HTML(5)、CSS(3)、JavaScript(ES5、ES6):编写一个个的页面 -> 给后端(PHP、Python、Go、Java) -> 后端嵌入模板语法 -> 后端渲染完数据 -> 返回数据给前端 -> 在浏览器中查看 Ajax的出现 -> 后台发送异步请

Vue 3深度探索:自定义渲染器与服务端渲染

这篇文章介绍了如何在Vue框架中实现自定义渲染器以增强组件功能,探讨了虚拟DOM的工作原理,以及如何通过SSR和服务端预取数据优化首屏加载速度。同时,讲解了同构应用的开发方式与状态管理技巧,助力构建高性能前端应用。

Vue第三方库与插件实战手册

这篇文章介绍了如何在Vue框架中实现数据的高效验证与处理,以及如何集成ECharts、D3.js、Chart.js等图表库优化数据可视化效果。同时,探讨了Progressive Web App(PWA)的接入与优化策略,以提升Web应用的用户体验与加载速度。

理解Vue 3响应式系统原理

title: 理解Vue 3响应式系统原理 date: 2024/5/28 15:44:47 updated: 2024/5/28 15:44:47 categories: 前端开发 tags: Vue3.x TypeScript SFC优化 Composition-API Ref&Reactive

Vue 3指令与事件处理

title: Vue 3指令与事件处理 date: 2024/5/25 18:53:37 updated: 2024/5/25 18:53:37 categories: 前端开发 tags: Vue3基础 指令详解 事件处理 高级事件 实战案例 最佳实践 性能优化 第1章 Vue 3基础 1.1 V

Vue 3 组件基础与模板语法详解

title: Vue 3 组件基础与模板语法详解 date: 2024/5/24 16:31:13 updated: 2024/5/24 16:31:13 categories: 前端开发 tags: Vue3特性 CompositionAPI Teleport Suspense Vue3安装 组件