最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3調(diào)度器scheduler功能和用法詳解

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

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

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

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

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

完整代碼:

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

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

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

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

相關(guān)文章

  • Vue插件之滑動驗證碼

    Vue插件之滑動驗證碼

    這篇文章主要為大家詳細紹介紹了Vue插件之滑動驗證碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Vue2.0 slot分發(fā)內(nèi)容與props驗證的方法

    Vue2.0 slot分發(fā)內(nèi)容與props驗證的方法

    本篇文章主要介紹了Vue2.0 slot分發(fā)內(nèi)容與props驗證的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • vue.js指令v-for使用及索引獲取

    vue.js指令v-for使用及索引獲取

    這篇文章主要為大家詳細介紹了vue.js中v-for使用及索引獲取,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • vue3+vite使用jsx和tsx詳情

    vue3+vite使用jsx和tsx詳情

    這篇文章主要介紹了vue3+vite使用jsx和tsx詳情,文章通過安裝@vitejs/plugin-vue-jsx展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • Vue中rem與postcss-pxtorem的應(yīng)用詳解

    Vue中rem與postcss-pxtorem的應(yīng)用詳解

    這篇文章主要介紹了Vue中rem與postcss-pxtorem的應(yīng)用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Ant Design Vue日期組件的時間限制方式

    Ant Design Vue日期組件的時間限制方式

    這篇文章主要介紹了Ant Design Vue日期組件的時間限制方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue3中ref獲取子組件的值代碼示例

    vue3中ref獲取子組件的值代碼示例

    這篇文章主要給大家介紹了關(guān)于vue3中ref獲取子組件值的相關(guān)資料,在Vue3中父組件獲取子組件的值可以通過使用'ref'和'$refs'來實現(xiàn),文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-08-08
  • vue-cli3 karma單元測試的實現(xiàn)

    vue-cli3 karma單元測試的實現(xiàn)

    這篇文章主要介紹了vue-cli3 karma單元測試的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Vue3 組件間通信之mitt實現(xiàn)任意組件間通信的步驟

    Vue3 組件間通信之mitt實現(xiàn)任意組件間通信的步驟

    mitt 主要有4個API:emit(觸發(fā)某個事件)、on(綁定事件)、off(解綁某個事件)、all(獲取所有綁定的事件),這篇文章主要介紹了Vue3 組件間通信之mitt實現(xiàn)任意組件間通信,需要的朋友可以參考下
    2024-05-05
  • 淺談vue生命周期共有幾個階段?分別是什么?

    淺談vue生命周期共有幾個階段?分別是什么?

    這篇文章主要介紹了淺談vue生命周期共有幾個階段?分別是什么?具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08

最新評論

东城区| 阜新| 兖州市| 康乐县| 河西区| 永寿县| 宝山区| 龙南县| 华坪县| 房山区| 曲水县| 岗巴县| 佛坪县| 衡水市| 青龙| 榆社县| 兰考县| 长海县| 云南省| 鹤壁市| 周口市| 西和县| 湘潭市| 石河子市| 福安市| 商都县| 绵竹市| 高安市| 会东县| 本溪市| 东海县| 麻江县| 永平县| 临泽县| 玉龙| 岳阳市| 铜鼓县| 沭阳县| 突泉县| 工布江达县| 怀集县|