亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

vue3調度器scheduler功能和用法詳解

 更新時間:2023年06月05日 10:02:27   作者:包子愛吃肉  
調度器是vue3響應式系統(tǒng)中一個非常重要的特性,可調度性指的是當trigger 動作觸發(fā)副作用函數重新執(zhí)行時,有能力決定副作用函數執(zhí)行的時機、次數以及方式,本文通過代碼示例給大家介紹調度器是什么,有什么功能,怎么使用,感興趣的同學可以借鑒閱讀

調度器是vue3響應式系統(tǒng)中一個非常重要的特性,可調度性指的是當trigger 動作觸發(fā)副作用函數重新執(zhí)行時,有能力決定副作用函數執(zhí)行的時機、次數以及方式

const data = { foo: 1 }
const obj = new Proxy(data, { /* ... */ })    // 上文中的響應式
 effect(() => {
 console.log(obj.foo)
 })
 obj.foo++
 console.log('結束了')

正常執(zhí)行結果順序是1,2,結束了,但是,若我們期望的打印順序發(fā)生改變1,結束了,2,要實現這樣的打印結果,就需要使用到調度器

  • 可以為函數effect函數設計一個選項參數options,允許用戶指定調度器:
    effect(
        () => {
          console.log(obj.foo);
        },
        // options
        {
          // 調度器 scheduler 是一個函數
          scheduler(fn) { 
            // ... 
         },
        });
  • 將調度器對象掛在到當前副作用函數中
    // effect 函數用于注冊副作用函數
      function effect(fn, options = {}) {
        fn.options = options; // 新增掛在調度器
        activeEffect = fn;
        // 執(zhí)行副作用函數
        fn();
      }
  • 修改參數時,判斷是否存在調度器,存在,執(zhí)行當前掛載中調度器方法(在taigger函數中)
   function trigger(target, key) {
        // 根據target從桶中取得depsMap,它是key --> effects
        const depsMap = bucket.get(target);
        if (!depsMap) return;
        // 根據key取得當前對應的副作用函數
        const effects = depsMap.get(key);
        // 執(zhí)行副作用函數
        effects && effects.forEach((fn) => {
        // fn()
            if (fn.options.scheduler) {    // 新增
              fn.options.scheduler(fn);
            } else {
              // 否則直接執(zhí)行副作用函數(之前的默認行為)
              fn();
            }
          });
      }
  • 使用 setTimeout 開啟一個宏任務來執(zhí)行副作用函數 fn,這樣,就能改變執(zhí)行順序,拿到我們想要的執(zhí)行結果
 function effect(fn, options = {}) {
        fn.options = options; // 新增
        activeEffect = fn;
        // 執(zhí)行副作用函數
        fn();
      }
      effect(
        () => {
          console.log(obj.foo);
        },
        // options
        {
          // 調度器 scheduler 是一個函數
          scheduler(fn) {
            // 修改參數,將副作用函數放在宏任務隊列中執(zhí)行
            setTimeout(fn)
          },
        }
      );

完整代碼:

 const data = { foo: 1 };
      // 用一個全局變量存儲被注冊的副作用函數
      let activeEffect;
      // 創(chuàng)建一個新桶來存儲副作用函數,包含key和value
      const bucket = new WeakMap();
      const obj = new Proxy(data, {
        get(target, key) {
          // target:當前對象,key:觸發(fā)監(jiān)聽的key
          track(target, key);
          return target[key];
        },
        set(target, key, newVal) {
          target[key] = newVal;
          trigger(target, key);
        },
      });
      // track函數
      function track(target, key) {
        // 沒有正在執(zhí)行的副作用函數 直接返回
        if (!activeEffect) return target[key];
        // 從這個桶中取出一個Map類型(key -> value)
        let depsMap = bucket.get(target);
        // 不存在,則創(chuàng)建一個Map與target關聯
        if (!depsMap) {
          bucket.set(target, (depsMap = new Map()));
        }
        // 根據key判斷每個key上是否存在對應的副作用函數
        let deps = depsMap.get(key);
        // 不存在,則新建一個new Set,并與key關聯
        if (!deps) {
          depsMap.set(key, (deps = new Set()));
        }
        // 最后將當前激活的副作用函數添加到桶中
        deps.add(activeEffect);
      }
      // trigger函數
      function trigger(target, key) {
        // 根據target從桶中取得depsMap,它是key --> effects
        const depsMap = bucket.get(target);
        if (!depsMap) return;
        // 根據key取得當前對應的副作用函數
        const effects = depsMap.get(key);
        // 執(zhí)行副作用函數
        effects &&
          effects.forEach((fn) => {
            if (fn.options.scheduler) {
              fn.options.scheduler(fn);
            } else {
              // 否則直接執(zhí)行副作用函數(之前的默認行為)
              fn();
            }
          });
      }
      // effect 函數用于注冊副作用函數
      function effect(fn, options = {}) {
        fn.options = options; // 新增
        activeEffect = fn;
        // 執(zhí)行副作用函數
        fn();
      }
      effect(
        () => {
          console.log(obj.foo);
        },
        // options
        {
          // 調度器 scheduler 是一個函數
          scheduler(fn) {
            // 修改參數,將副作用函數放在宏任務隊列中執(zhí)行
            setTimeout(fn);
          },
        }
      );
      obj.foo++;
      console.log("結束了");

除了控制副作用函數的執(zhí)行順序,通過調度器還可以做到控制它的執(zhí)行次數

  • 正常的打印結果應該是1,2,3,但是我們只關心執(zhí)行的最后結果,應該拿到的是1,3,執(zhí)行三次有些多余,這時,就需要使用到調度器來修改執(zhí)行次數
const data = { foo: 1 }
const obj = new Proxy(data, { /* ... */ })    // 上文中的響應式
 effect(() => {
 console.log(obj.foo)
 })
 obj.foo++
 obj.foo++;
  • 實現不包含過渡階段,使用調度器基于promise,可以直接修改當前當前調度函數
    // 定義一個任務隊列,使用它自動去重能力
      const jobQueue = new Set();
      // 使用 Promise.resolve() 創(chuàng)建一個 promise 實例,我們用它將一個任務添加到微任務隊列
      const p = Promise.resolve();
      // 一個標志代表是否正在刷新隊列
      let isFlushing = false;
      function flushJob() {
        // 如果隊列正在刷新,則什么都不做
        if (isFlushing) return;
        // 設置為 true,代表正在刷新
        isFlushing = true;
        // 在微任務隊列中刷新 jobQueue 隊列
        p.then(() => {
          jobQueue.forEach((job) => job());
        }).finally(() => {
          // 結束后重置 isFlushing
          isFlushing = false;
        });
      }
  • 執(zhí)行調度函數
   effect(
        () => {
          console.log(obj.foo);
        },
        // options
        {
          // 調度器 scheduler 是一個函數
          scheduler(fn) {
            jobQueue.add(fn);
            // 調用 flushJob 刷新隊列
            flushJob();
          },
        }
      );
      obj.foo++;
      obj.foo++;

到此這篇關于vue3調度器scheduler功能和用法詳解的文章就介紹到這了,更多相關vue3調度器scheduler內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • vue3+vite+tdesign實現日歷式可編輯的排課班表填寫功能

    vue3+vite+tdesign實現日歷式可編輯的排課班表填寫功能

    本文介紹了如何使用Vue3和tdesign實現一個日歷式、可編輯的排班填寫功能,開發(fā)過程中面臨了年份和月份下拉框的實現、周期顯示以及可編輯日歷的樣式和數據獲取等挑戰(zhàn),感興趣的朋友一起看看吧
    2025-01-01
  • vue.js入門教程之綁定class和style樣式

    vue.js入門教程之綁定class和style樣式

    小編之前介紹了通過vue.js計算屬性,不知道大家都學會了嗎。那這篇文章中我們將一起學習vue.js實現綁定class和style樣式,有需要的朋友們可以參考借鑒。
    2016-09-09
  • vue實現web在線聊天功能

    vue實現web在線聊天功能

    這篇文章主要為大家詳細介紹了vue實現web在線聊天功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 代碼詳解Vuejs響應式原理

    代碼詳解Vuejs響應式原理

    這篇文章主要介紹了代碼詳解Vuejs響應式原理的基礎知識,有興趣的朋友們參考學習下吧。
    2017-12-12
  • Vue3自定義drag指令詳解

    Vue3自定義drag指令詳解

    這篇文章主要為大家詳細介紹了Vue3自定義drag指令的相關知識,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-12-12
  • Vue3.0 手寫放大鏡效果

    Vue3.0 手寫放大鏡效果

    放大鏡在很多購物網站都可以看的到,本文主要實現 固定放大兩倍,鼠標進入到左側圖片區(qū)域的時候,遮罩層顯示,離開時,遮罩層隱藏,感興趣的可以了解一下
    2021-07-07
  • 一文解決vue2 element el-table自適應高度問題

    一文解決vue2 element el-table自適應高度問題

    在寫公司后臺項目的時候遇到一個需求,要求表格頁面不能有滾動條,所以必須封裝一個公共方法來實現表格自適應高度,本問小編給大家介紹了如何解決vue2 element el-table自適應高度問題,需要的朋友可以參考下
    2023-11-11
  • Vue瀑布流插件的使用示例

    Vue瀑布流插件的使用示例

    這篇文章主要介紹了Vue瀑布流插件的使用示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • vue中的Key值重復問題

    vue中的Key值重復問題

    這篇文章主要介紹了vue中的Key值重復問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue中Element?UI組件庫使用方法詳解

    Vue中Element?UI組件庫使用方法詳解

    ElementUI是Vue的UI框架,提供了豐富的組件,方便快速開發(fā)頁面,本文詳細介紹了ElementUI的安裝、使用方法以及常見組件的說明,包括基礎組件、布局組件、選擇框組件、輸入框組件、下拉框組件等,需要的朋友可以參考下
    2024-11-11

最新評論