成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

你知道嗎?大部分人對于 Promise 的開發程度遠遠不足 10%!

開發 前端
大家都知道?Promise?是 JavaScript 的一個非常強大的特性,但是很多人對于?Promise?的認識還停留在?網絡請求上?,而網絡請求大部分人都用?axios,axios?已經幫我們封裝好了,所以自然而然地,大部分人在項目中并沒有過多使用過?Promise?這個強大的特性。

大家都知道 Promise 是 JavaScript 的一個非常強大的特性,但是很多人對于 Promise 的認識還停留在 網絡請求上 ,而網絡請求大部分人都用 axios,axios 已經幫我們封裝好了,所以自然而然地,大部分人在項目中并沒有過多使用過 Promise 這個強大的特性。

接下來總結一下我在項目中用到的 Promise 的場景。

打開彈窗的事件回調

如下場景,因為邏輯比較多,我封裝了一個 useModal 的 Hook,并在頁面中去調用,打開彈窗,打開彈窗的時候,接收兩個回調:

  • onSuccess:成功的回調
  • onError:失敗的回調

因為我需要在頁面調用的時候,成功和失敗之后都需要在頁面中做一些額外的操作。

圖片圖片

接著我在頁面中去調用這個 Hook,并使用了 open 方法,傳入兩個回調。

圖片圖片

不過后來我想了一下,如果我對于這個 Modal,只在乎 成功回調 和 失敗回調 的話,那可不可以直接 鏈式調用就行了呢?,就類似于下面這樣,有點類似于那些組件庫中的 form.validate 方法,也是返回一個 Promise。

圖片圖片

那么就得借助 Promise 的力量了。

圖片圖片

充當發布訂閱

說到發布訂閱,大家就想到了 EventBus、EventEmit 這些具備 emit、on 的元素,但是有時候我們所需要的 發布訂閱 并不需要這么復雜。

我們需要的可能只是,頁面1 完成了某件事情后,通知一下 頁面2,僅此而已。

我們需要先封裝一個 onReadyFn 的工具函數,這函數返回兩個東西。

  • readyResolve: 一個resolve函數
  • onReady: 接收回調函數,只有在readyResolve執行后才會執行

圖片圖片

接著封裝一個 usePage1.ts,用來處理 Page1 的邏輯,并在處理完邏輯后發布通知。

圖片圖片

圖片圖片

現在通知有了,只需要訂閱即可。

圖片圖片

可以到控制臺里,看到了這個運行順序是符合我們的預期的

圖片圖片

檢測接口請求超時

我們使用 axios 的時候可以設置 timeout 去控制接口的超時時間,但是有的項目并沒有用 axios 那咋辦呢?那就得自己去檢測接口請求超時啦。

大概思路是這樣的,比如你設置的超時時長是 2000ms。

  • 讓實際請求跟一個 2000ms 的定時器去賽跑
  • 定時器先執行完,則說明實際請求超時了
  • 實際請求先執行完,則說明沒有超時

說到賽跑,咱們第一時間可以想到 Promise.race,是的,就是用它來檢測接口超時。

圖片圖片

圖片圖片

控制多并發

提起控制并發,大家應該不陌生,我們可以先來看看多并發,再去聊聊為什么要去控制它。

多并發一般是指多個異步操作同時進行,而運行的環境中資源是有限的,短時間內過多的并發,會對所運行的環境造成很大的壓力,比如前端的瀏覽器,后端的服務器,常見的多并發操作有:

  • 前端的多個接口同時請求
  • 前端多條數據異步處理
  • Nodejs的多個數據操作同時進行
  • Nodejs對多個文件同時進行修改

圖片圖片

正是因為多并發會造成壓力,所以我們才需要去控制他,降低這個壓力~,比如我可以控制最大并發數是 3,這樣的話即使有100個并發,我也能保證最多同時并發的最大數量是 3。

圖片圖片

大致實現思路就是,假設現在有 9 個并發,我設置最大并發為 3,那么我將會走下面這些步驟:

  • 1、先定好三個坑位
  • 2、讓前三個并發進去坑位執行
  • 3、看哪個坑位并發先執行完,就從剩余的并發中拿一個進去補坑
  • 4、一直重復第 3 步,一直到所有并發執行完

圖片圖片

在進行多并發的時候,我們通常會使用 Promise.all ,但是 Promise.all并不能控制并發,或者說它本來就沒這個能力,我們可以看下面的例子。

圖片圖片

最后是同時輸出,這說明這幾個并發是同時發生的。

圖片圖片

期望效果

圖片圖片

圖片圖片

實現 limitFn

我們需要在函數內部維護兩個變量:

  • queue:隊列,用來存每一個改造過的并發
  • activeCount:用來記錄正在執行的并發數

并聲明函數 generator ,這個函數返回一個 Promise,因為 Promise.all 最好是接收一個 Promise 數組。

圖片圖片

接下來我們來實現 enqueue 這個函數做兩件事:

  • 將每一個 fetchFn 放進隊列里
  • 將坑位里的 fetchFn 先執行

圖片圖片

假如我設置最大并發數為 2,那么這一段代碼在一開始的時候只會執行 2 次,因為一開始只會有 2 次符合 if 判斷,大家可以思考一下為什么~

圖片圖片

一開始執行 2 次,說明這時候兩個坑位已經各自有一個 fetchFn 在執行了。

接下來我們實現 run 函數,這個函數是用來包裝 fetch 的,他完成幾件事情:

1、將 activeCount++ ,這時候執行中的并發數 +1

2、將 fetchFn 執行,并把結果 resolve 出去,說明這個并發執行完了

3、將 activeCount--,這時候執行中的并發數 -1

4、從 queue 中取一個并發,拿來補坑執行

圖片圖片

其實第 3、4 步,是在 next 函數里面執行的

圖片圖片

代碼

充當發布訂閱

// hooks/onReadyFn
export const onReadyFn = () => {
  let readyResolve: any = null;
  const readyPromise = new Promise(resolve => {
    // 把 resolve 保存起來
    readyResolve = resolve;
  });
  const onReady = (cb: (...args: any[]) => void) => {
    readyPromise.then((...args: any[]) => {
      // resolve 執行完才會走 then
      // 才會執行回調函數
      cb(...args);
    });
  };

  return {
    onReady,
    readyResolve,
  };
};

接口超時

// 模擬實際請求
const fetchFn = (delay: number) => {
  return new Promise<number>(resolve => {
    setTimeout(() => {
      resolve(1);
    }, delay);
  });
};

// 判斷是否超時
const checkTimeout = (delay: number, timeout: number) => {
  return Promise.race([
    fetchFn(delay),
    new Promise((_, reject) => {
      setTimeout(() => {
        reject('超時啦!');
      }, timeout);
    }),
  ]);
};

// 沒超時
checkTimeout(100, 500)
  .then(res => {
    console.log('沒超時', res);
  })
  .catch(err => {
    console.log(err);
  });

// 超時了
checkTimeout(600, 500)
  .then(res => {
    console.log('沒超時', res);
  })
  .catch(err => {
    console.log(err);
  });

控制并發

const limitFn = (limit) => {
  const queue = [];
  let activeCount = 0;

  const next = () => {
    activeCount--;

    if (queue.length > 0) {
      queue.shift()();
    }
  };

  const run = async (fn, resolve, ...args) => {
    activeCount++;

    const result = (async () => fn(...args))();


    try {
      const res = await result;
      resolve(res);
    } catch { }

    next();
  };

  const enqueue = (fn, resolve, ...args) => {
    queue.push(run.bind(null, fn, resolve, ...args));

    if (activeCount < limit && queue.length > 0) {
      queue.shift()();
    }
  };

  const generator = (fn, ...args) =>
    new Promise((resolve) => {
      enqueue(fn, resolve, ...args);
    });

  return generator;
};

責任編輯:武曉燕 來源: 前端之神
相關推薦

2011-12-26 17:13:18

iPad統計App

2024-08-01 17:34:56

Promiseaxios請求

2019-06-14 15:36:13

Windows 10安全PC

2018-11-25 21:53:10

人工智能AI開發者

2012-06-07 16:16:43

JavaScript

2025-01-26 16:04:09

2016-10-26 10:23:42

2022-05-18 09:49:26

MySQLID數據庫

2023-12-12 08:41:01

2016-12-22 08:38:21

2024-04-15 00:04:00

APP開發

2023-02-07 13:51:11

SQLupdate語句

2024-09-18 07:00:00

消息隊列中間件消息隊列

2022-09-29 15:32:58

云計算計算模式

2021-10-14 06:52:47

算法校驗碼結構

2024-08-06 11:27:23

LLM鏈系統AI

2024-11-20 08:31:49

前端全棧技術

2024-05-28 09:12:10

2024-04-07 00:00:00

ESlint命令變量

2019-12-12 09:23:29

Hello World操作系統函數庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: a成人| 一级黄色片免费在线观看 | 欧美日韩在线免费 | 久久久噜噜噜www成人网 | 日韩免费福利视频 | 91精品国产乱码久久久 | 日韩免费一区二区 | 神马久久久久久久久久 | 一区二区不卡高清 | 欧美中文字幕在线 | 欧美激情一区二区三区 | 国产在线视频在线观看 | 自拍 亚洲 欧美 老师 丝袜 | 97中文视频 | 精品欧美乱码久久久久久1区2区 | 99国产精品视频免费观看一公开 | 国产亚洲一区精品 | 国产线视频精品免费观看视频 | 一级黄色生活视频 | 草草草影院 | 福利av在线 | 亚洲久视频 | 成人一区在线观看 | 精品福利在线 | 久久成人国产 | 黑人巨大精品欧美一区二区一视频 | 久久久激情视频 | 国产亚洲欧美另类一区二区三区 | 久久久精品 | 欧美一区在线视频 | 蜜桃视频在线观看免费视频网站www | 日本一区二区三区精品视频 | 99免费在线观看视频 | 成人福利在线观看 | 日本久久久影视 | 国产丝袜一区二区三区免费视频 | 青草福利| 久草新在线 | 91精品久久久久久久久久 | 6996成人影院网在线播放 | 国产偷录叫床高潮录音 |