日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

用30行代碼封裝一個(gè)工具,解決Promise的多并發(fā)問(wèn)題

來(lái)源: 責(zé)編: 時(shí)間:2024-06-05 17:46:46 147觀看
導(dǎo)讀背景提起控制并發(fā),大家應(yīng)該不陌生,我們可以先來(lái)看看多并發(fā),再去聊聊為什么要去控制它。多并發(fā)一般是指多個(gè)異步操作同時(shí)進(jìn)行,而運(yùn)行的環(huán)境中資源是有限的,短時(shí)間內(nèi)過(guò)多的并發(fā),會(huì)對(duì)所運(yùn)行的環(huán)境造成很大的壓力,比如前端的瀏覽

背景

提起控制并發(fā),大家應(yīng)該不陌生,我們可以先來(lái)看看多并發(fā),再去聊聊為什么要去控制它。ZHu28資訊網(wǎng)——每日最新資訊28at.com

多并發(fā)一般是指多個(gè)異步操作同時(shí)進(jìn)行,而運(yùn)行的環(huán)境中資源是有限的,短時(shí)間內(nèi)過(guò)多的并發(fā),會(huì)對(duì)所運(yùn)行的環(huán)境造成很大的壓力,比如前端的瀏覽器,后端的服務(wù)器,常見(jiàn)的多并發(fā)操作有:ZHu28資訊網(wǎng)——每日最新資訊28at.com

  • 前端的多個(gè)接口同時(shí)請(qǐng)求
  • 前端多條數(shù)據(jù)異步處理
  • Nodejs的多個(gè)數(shù)據(jù)操作同時(shí)進(jìn)行
  • Nodejs對(duì)多個(gè)文件同時(shí)進(jìn)行修改

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

正是因?yàn)槎嗖l(fā)會(huì)造成壓力,所以我們才需要去控制他,降低這個(gè)壓力~,比如我可以控制最大并發(fā)數(shù)是 3,這樣的話即使有100個(gè)并發(fā),我也能保證最多同時(shí)并發(fā)的最大數(shù)量是 3。ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

代碼實(shí)現(xiàn)

實(shí)現(xiàn)思路

大致思路就是,假設(shè)現(xiàn)在有 9 個(gè)并發(fā),我設(shè)置最大并發(fā)為 3,那么我將會(huì)走下面這些步驟:ZHu28資訊網(wǎng)——每日最新資訊28at.com

1、先定好三個(gè)坑位ZHu28資訊網(wǎng)——每日最新資訊28at.com

2、讓前三個(gè)并發(fā)進(jìn)去坑位執(zhí)行ZHu28資訊網(wǎng)——每日最新資訊28at.com

3、看哪個(gè)坑位并發(fā)先執(zhí)行完,就從剩余的并發(fā)中拿一個(gè)進(jìn)去補(bǔ)坑ZHu28資訊網(wǎng)——每日最新資訊28at.com

4、一直重復(fù)第 3 步,一直到所有并發(fā)執(zhí)行完ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

Promise.all

在進(jìn)行多并發(fā)的時(shí)候,我們通常會(huì)使用Promise.all,但是Promise.all并不能控制并發(fā),或者說(shuō)它本來(lái)就沒(méi)這個(gè)能力,我們可以看下面的例子:ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

最后是同時(shí)輸出,這說(shuō)明這幾個(gè)并發(fā)是同時(shí)發(fā)生的。ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

所以我們需要做一些改造,讓Promise.all執(zhí)行 promises 時(shí)支持控制并發(fā),但是我們改造的不應(yīng)該是Promise.all,而是這一個(gè)個(gè)的fetchFn。ZHu28資訊網(wǎng)——每日最新資訊28at.com

期望效果

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

實(shí)現(xiàn) limitFn

我們需要在函數(shù)內(nèi)部維護(hù)兩個(gè)變量:ZHu28資訊網(wǎng)——每日最新資訊28at.com

  • queue:隊(duì)列,用來(lái)存每一個(gè)改造過(guò)的并發(fā)
  • activeCount:用來(lái)記錄正在執(zhí)行的并發(fā)數(shù)

并聲明函數(shù) generator ,這個(gè)函數(shù)返回一個(gè) Promise,因?yàn)?Promise.all 最好是接收一個(gè) Promise 數(shù)組。ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

接下來(lái)我們來(lái)實(shí)現(xiàn) enqueue 這個(gè)函數(shù)做兩件事:ZHu28資訊網(wǎng)——每日最新資訊28at.com

  • 將每一個(gè) fetchFn 放進(jìn)隊(duì)列里
  • 將坑位里的 fetchFn 先執(zhí)行

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

假如我設(shè)置最大并發(fā)數(shù)為 2,那么這一段代碼在一開(kāi)始的時(shí)候只會(huì)執(zhí)行 2 次,因?yàn)橐婚_(kāi)始只會(huì)有 2 次符合 if 判斷,大家可以思考一下為什么!ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

一開(kāi)始執(zhí)行 2 次,說(shuō)明這時(shí)候兩個(gè)坑位已經(jīng)各自有一個(gè) fetchFn 在執(zhí)行了。ZHu28資訊網(wǎng)——每日最新資訊28at.com

接下來(lái)我們實(shí)現(xiàn) run 函數(shù),這個(gè)函數(shù)是用來(lái)包裝 fetch 的,他完成幾件事情:ZHu28資訊網(wǎng)——每日最新資訊28at.com

1、將 activeCount++ ,這時(shí)候執(zhí)行中的并發(fā)數(shù) +1ZHu28資訊網(wǎng)——每日最新資訊28at.com

2、將 fetchFn 執(zhí)行,并把結(jié)果 resolve 出去,說(shuō)明這個(gè)并發(fā)執(zhí)行完了ZHu28資訊網(wǎng)——每日最新資訊28at.com

3、將 activeCount--,這時(shí)候執(zhí)行中的并發(fā)數(shù) -1ZHu28資訊網(wǎng)——每日最新資訊28at.com

4、從 queue 中取一個(gè)并發(fā),拿來(lái)補(bǔ)坑執(zhí)行ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

其實(shí)第 3、4 步,是在 next 函數(shù)里面執(zhí)行的。ZHu28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片ZHu28資訊網(wǎng)——每日最新資訊28at.com

完整代碼

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;};

這不是我寫(xiě)的

其實(shí)這是一個(gè)很出名的庫(kù)的源碼,就是p-limit,哈哈,但是重要嗎?知識(shí)嘛,讀懂了,它就是你的,到時(shí)跟面試官嘮嗑的時(shí)候,他哪知道是不是真的是你寫(xiě)的!ZHu28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-92182-0.html用30行代碼封裝一個(gè)工具,解決Promise的多并發(fā)問(wèn)題

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 短短幾年,為什么 Vite 會(huì)變得這么受歡迎?

下一篇: Tailwind Classes 我希望早點(diǎn)知道的

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
Top 主站蜘蛛池模板: 常德市| 朝阳区| 额济纳旗| 宿松县| 琼结县| 茌平县| 利川市| 福建省| 小金县| 上蔡县| 康保县| 印江| 吴堡县| 山东省| 莲花县| 汉中市| 霞浦县| 金华市| 涟水县| 习水县| 台东县| 孙吴县| 黄龙县| 清徐县| 勃利县| 称多县| 新乡县| 陆川县| 大城县| 海晏县| 大石桥市| 海伦市| 贵定县| 武陟县| 沂南县| 永福县| 梓潼县| 陆丰市| 比如县| 沧州市| 柯坪县|