精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

手寫 p-limit,40 行代碼實(shí)現(xiàn)并發(fā)控制

開發(fā) 前端
實(shí)現(xiàn)并發(fā)控制只要 40 多行代碼,其實(shí)這就是 p-limit 的源碼了,大家感興趣也可以自己實(shí)現(xiàn)一下。

前端代碼經(jīng)常要處理各種異步邏輯。

有的是串行的:

const promise1 = new Promise(function(resolve) {
// 異步邏輯 1...
resolve();
});
const promise2 = new Promise(function(resolve) {
// 異步邏輯 2...
resolve();
});

promise1.then(() => promise2);
await promise1;
await promise2;

有的是并行的:

await Promise.all([promise1, promise2]);
await Promise.race([promise1, promise2]);

并行的異步邏輯有時(shí)還要做并發(fā)控制。

并發(fā)控制是常見的需求,也是面試常考的面試題。

一般我們會(huì)用 p-limit 來做:

import pLimit from 'p-limit';

const limit = pLimit(2);

const input = [
limit(() => fetchSomething('foo')),
limit(() => fetchSomething('bar')),
limit(() => doSomething())
];

const result = await Promise.all(input);
console.log(result);

比如上面這段邏輯,就是幾個(gè)異步邏輯并行執(zhí)行,并且最大并發(fā)是 2。

那如何實(shí)現(xiàn)這樣的并發(fā)控制呢?

我們自己來寫一個(gè):

首先,要傳入并發(fā)數(shù)量,返回一個(gè)添加并發(fā)任務(wù)的函數(shù),我們把它叫做 generator:

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

return generator;
}

這里添加的并發(fā)任務(wù)要進(jìn)行排隊(duì),所以我們準(zhǔn)備一個(gè) queue,并記錄當(dāng)前在進(jìn)行中的異步任務(wù)。

const queue = [];
let activeCount = 0;

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

添加的異步任務(wù)就入隊(duì),也就是 enqueue。

enqueue 做的事情就是把一個(gè)異步任務(wù)添加到 queue 中,并且只要沒達(dá)到并發(fā)上限就再執(zhí)行一批任務(wù):

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

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

具體運(yùn)行的邏輯是這樣的:

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

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

resolve(result);

try {
await result;
} catch {}

next();
};

計(jì)數(shù),運(yùn)行這個(gè)函數(shù),改變最后返回的那個(gè) promise 的狀態(tài),然后執(zhí)行完之后進(jìn)行下一步處理:

下一步處理自然就是把活躍任務(wù)數(shù)量減一,然后再跑一個(gè)任務(wù):

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

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

這樣就保證了并發(fā)的數(shù)量限制。

現(xiàn)在的全部代碼如下,只有 40 行代碼:

const pLimit = (concurrency) => {  
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))();

resolve(result);

try {
await result;
} catch {}

next();
};

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

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

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

return generator;
};

這就已經(jīng)實(shí)現(xiàn)了并發(fā)控制。

不信我們跑跑看:

準(zhǔn)備這樣一段測(cè)試代碼:

const limit = pLimit(2);

function asyncFun(value, delay) {
return new Promise((resolve) => {
console.log('start ' + value);
setTimeout(() => resolve(value), delay);
});
}

(async function () {
const arr = [
limit(() => asyncFun('aaa', 2000)),
limit(() => asyncFun('bbb', 3000)),
limit(() => asyncFun('ccc', 1000)),
limit(() => asyncFun('ccc', 1000)),
limit(() => asyncFun('ccc', 1000))
];

const result = await Promise.all(arr);
console.log(result);
})();

沒啥好說的,就是 setTimeout + promise,設(shè)置不同的 delay 時(shí)間。

并發(fā)數(shù)量為 2。

我們?cè)囅拢?/p>

圖片

先并發(fā)執(zhí)行前兩個(gè)任務(wù),2s 的時(shí)候一個(gè)任務(wù)執(zhí)行完,又執(zhí)行了一個(gè)任務(wù),然后再過一秒,都執(zhí)行完了,有同時(shí)執(zhí)行了兩個(gè)任務(wù)。

經(jīng)過測(cè)試,我們已經(jīng)實(shí)現(xiàn)了并發(fā)控制!

回顧一下我們實(shí)現(xiàn)的過程,其實(shí)就是一個(gè)隊(duì)列來保存任務(wù),開始的時(shí)候一次性執(zhí)行最大并發(fā)數(shù)的任務(wù),然后每執(zhí)行完一個(gè)啟動(dòng)一個(gè)新的。

還是比較簡(jiǎn)單的。

上面的 40 行代碼是最簡(jiǎn)化的版本,其實(shí)還有一些可以完善的地方,我們繼續(xù)完善一下。

首先,我們要把并發(fā)數(shù)暴露出去,還要讓開發(fā)者可以手動(dòng)清理任務(wù)隊(duì)列。

我們這樣寫:

Object.defineProperties(generator, {
activeCount: {
get: () => activeCount
},
pendingCount: {
get: () => queue.length
},
clearQueue: {
value: () => {
queue.length = 0;
}
}
});

用 Object.defineProperties 只定義 get 函數(shù),這樣 activeCount、pendingCount 就是只能讀不能改的。

同時(shí)還提供了一個(gè)清空任務(wù)隊(duì)列的函數(shù)。

然后傳入的參數(shù)也加個(gè)校驗(yàn)邏輯:

if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
}

不是整數(shù)或者小于 0 就報(bào)錯(cuò),當(dāng)然,Infinity 也是可以的。

最后,其實(shí)還有一個(gè)特別需要完善的點(diǎn),就是這里:

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

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

應(yīng)該改成這樣:

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

(async () => {
await Promise.resolve();

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

因?yàn)?activeCount-- 的邏輯是在執(zhí)行完任務(wù)之后才執(zhí)行的,萬一任務(wù)還沒執(zhí)行完,這時(shí)候 activeCount 就是不準(zhǔn)的。

所以為了保證并發(fā)數(shù)量能控制準(zhǔn)確,要等全部的微任務(wù)執(zhí)行完再拿 activeCount。

怎么在全部的微任務(wù)執(zhí)行完再執(zhí)行邏輯呢?

加一個(gè)新的微任務(wù)不就行了?

所以有這樣的 await Promise.resolve(); 的邏輯。

這樣,就是一個(gè)完善的并發(fā)控制邏輯了,p-limit 也是這么實(shí)現(xiàn)的。

感興趣的同學(xué)可以自己試一下:

const pLimit = (concurrency) => {
if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) {
throw new TypeError('Expected `concurrency` to be a number from 1 and up');
}

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))();

resolve(result);

try {
await result;
} catch {}

next();
};

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

(async () => {
await Promise.resolve();

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

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

Object.defineProperties(generator, {
activeCount: {
get: () => activeCount
},
pendingCount: {
get: () => queue.length
},
clearQueue: {
value: () => {
queue.length = 0;
}
}
});

return generator;
};

const limit = pLimit(2);

function asyncFun(value, delay) {
return new Promise((resolve) => {
console.log('start ' + value);
setTimeout(() => resolve(value), delay);
});
}

(async function () {
const arr = [
limit(() => asyncFun('aaa', 2000)),
limit(() => asyncFun('bbb', 3000)),
limit(() => asyncFun('ccc', 1000)),
limit(() => asyncFun('ccc', 1000)),
limit(() => asyncFun('ccc', 1000))
];

const result = await Promise.all(arr);
console.log(result);
})();

總結(jié)

js 代碼經(jīng)常要處理異步邏輯的串行、并行,還可能要做并發(fā)控制,這也是面試常考的點(diǎn)。

實(shí)現(xiàn)并發(fā)控制的核心就是通過一個(gè)隊(duì)列保存所有的任務(wù),然后最開始批量執(zhí)行一批任務(wù)到最大并發(fā)數(shù),然后每執(zhí)行完一個(gè)任務(wù)就再執(zhí)行一個(gè)新的。

其中要注意的是為了保證獲取的任務(wù)數(shù)量是準(zhǔn)確的,要在所有微任務(wù)執(zhí)行完之后再獲取數(shù)量。

實(shí)現(xiàn)并發(fā)控制只要 40 多行代碼,其實(shí)這就是 p-limit 的源碼了,大家感興趣也可以自己實(shí)現(xiàn)一下。

責(zé)任編輯:武曉燕 來源: 神光的編程秘籍
相關(guān)推薦

2022-04-15 08:07:21

ReactDiff算法

2017-03-28 21:03:35

代碼React.js

2017-07-24 15:06:02

代碼人臉識(shí)別實(shí)踐

2021-08-08 08:08:20

木馬無文件Cobalt Stri

2021-01-12 10:22:45

JavaScript并發(fā)控制前端

2021-04-07 06:00:18

JavaScript 前端并發(fā)控制

2009-02-09 10:06:03

并發(fā)控制Web應(yīng)用悲觀鎖

2015-05-08 09:58:26

程序員代碼

2021-07-19 09:25:19

數(shù)據(jù)庫(kù)MySQL技術(shù)

2017-08-21 10:56:55

MySQL并發(fā)控制

2018-01-23 09:17:22

Python人臉識(shí)別

2020-12-17 08:06:33

CSS 日歷界面

2022-09-25 23:10:53

Python數(shù)據(jù)集機(jī)器學(xué)習(xí)

2012-07-23 09:58:50

代碼程序員

2022-03-26 22:28:06

加密通信Python

2022-04-09 09:11:33

Python

2010-05-25 15:12:22

MySQL分頁(yè)

2024-10-07 10:02:28

2024-06-17 08:40:16

2022-12-12 09:07:06

Redis并發(fā)限流
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

免费看成人哺乳视频网站| 国产三级电影在线| 亚洲国产国产亚洲一二三| 亚洲精品视频在线观看视频| 亚洲国产精品三区| 日本一本在线免费福利| 99re在线视频这里只有精品| 国产日韩中文字幕| 日韩激情在线播放| 99精品视频精品精品视频| 精品国产凹凸成av人导航| 无码少妇一区二区三区芒果| 91麻豆一二三四在线| 久久久久成人黄色影片| 91久久国产自产拍夜夜嗨| 亚洲GV成人无码久久精品 | 日韩av中文字幕一区二区三区| 久久视频在线直播| 亚洲激情视频小说| 国产精品三p一区二区| 欧美日韩免费视频| 成年人视频网站免费观看| 成人在线app| 国产片一区二区| 精品欧美国产| 国产91麻豆视频| 国产一区二区不卡| 国产精品中文在线| 欧美一区二区三区久久久| 黄色精品网站| 欧美成人精品不卡视频在线观看| 欧美人妻一区二区三区| 日韩成人一级| 亚洲国产欧美久久| 日韩大尺度视频| 日本免费成人| 欧美日韩高清一区| wwwwww.色| 国产日韩另类视频一区| 精品免费在线观看| 国产精品入口芒果| 在线中文字幕视频观看| 亚洲日本在线天堂| 在线观看免费黄色片| 免费观看在线黄色网| 国产女人水真多18毛片18精品视频| 欧美成熟毛茸茸复古| 天天干天天爽天天操| 成人深夜在线观看| 99精品国产高清在线观看| 国产欧美综合视频| 国产乱码字幕精品高清av| 国产一区深夜福利| 91激情在线观看| 久久66热re国产| 成人免费视频网| 国产手机视频在线| 国产九九视频一区二区三区| 99久久无色码| 天堂av资源网| 久久先锋影音av鲁色资源网| 青青草原亚洲| 91欧美在线视频| 亚洲欧洲一区二区三区| gogogo免费高清日本写真| 麻豆视频在线| 一区av在线播放| 少妇人妻大乳在线视频| 黄色污网站在线观看| 日韩欧美精品网址| 久久国产这里只有精品| 国产剧情一区二区在线观看| 欧美白人最猛性xxxxx69交| 亚洲欧美日韩色| 中文字幕亚洲影视| 上原亚衣av一区二区三区| 黑鬼狂亚洲人videos| 亚洲午夜精品久久久久久app| 韩国日本不卡在线| www.久久久久久久| 黑人精品欧美一区二区蜜桃| 97人摸人人澡人人人超一碰| 四虎影视在线观看2413| 国产欧美视频一区二区| 热这里只有精品| 九九色在线视频| 日韩人体视频一二区| 性chinese极品按摩| 日韩精品一区二区三区中文在线 | 日韩av视屏| 国产精品美女www爽爽爽| 日韩精品第1页| 中老年在线免费视频| 欧美美女网站色| 天天插天天射天天干| 色男人天堂综合再现| 久久免费在线观看| 在线不卡免费视频| 成人黄色小视频在线观看| 日本不卡高清视频一区| 欧美极品少妇videossex| 欧美性受xxxx| 91玉足脚交白嫩脚丫| 久久社区一区| 5278欧美一区二区三区| 国产免费不卡av| 久久婷婷成人综合色| 无码毛片aaa在线| 日韩欧美另类一区二区| 日韩欧美国产麻豆| 免费视频91蜜桃| 99国产成+人+综合+亚洲欧美| 国产一区视频在线播放| 青青在线免费观看视频| 无码人妻丰满熟妇奶水区码| 国产精品自拍一区| 欧美一级二级三级九九九| 香蕉成人app免费看片| 欧美午夜一区二区三区| 国产精品成人99一区无码| 国产高清一区| 国产精品99一区| 五月天婷婷社区| 亚洲精品大片www| 麻豆三级在线观看| 亚洲春色h网| 午夜精品一区二区三区在线视频| 国产精品久久久久久免费| 国产日韩欧美激情| 国产亚洲天堂网| 久久男人av| 欧美成人三级视频网站| 国产精品久久久久久在线| 欧美激情一区在线观看| 哪个网站能看毛片| 性欧美lx╳lx╳| 97在线免费观看视频| 亚洲乱码在线观看| 亚洲精品视频一区| 国产精品久久久久久9999| 97欧美在线视频| 国产精选久久久久久| 永久免费在线观看视频| 欧美专区日韩专区| 级毛片内射视频| 老司机精品视频网站| 欧美另类一区| jizz内谢中国亚洲jizz| 亚洲精品自产拍| 日韩免费av网站| 欧美激情综合网| 污色网站在线观看| 97精品国产一区二区三区 | 亚洲精品一区二区三区av| 快播电影网址老女人久久| 亚洲欧美日韩久久久久久| youjizz在线视频| 久久精品人人做人人综合| 亚洲老女人av| 亚洲第一偷拍| 国产精品久久久久av福利动漫| 国产伦理精品| 亚洲网在线观看| 亚洲自拍第二页| 依依成人精品视频| 在线看黄色的网站| 丝袜美腿一区二区三区| 午夜精品一区二区在线观看 | 久久三级福利| 亚洲精品tv久久久久久久久| 日韩久久99| 久久免费精品视频| 免费播放片a高清在线观看| 欧美三级日韩三级国产三级| 成人在线观看高清| av资源网一区| 成人免费在线观看视频网站| 影视亚洲一区二区三区| 国产伦精品一区二区三区免费视频| 一个人看的www视频在线免费观看 一个人www视频在线免费观看 | 情事1991在线| 男女啪啪在线观看| 精品99久久久久久| 少妇又紧又色又爽又刺激视频| 日韩久久一区二区| 日本xxxx裸体xxxx| 久久国内精品视频| 久久久亚洲精品无码| 成人免费在线播放| 国产精品久久久久久久免费大片 | 无码国产69精品久久久久同性| 激情小说亚洲一区| 欧美变态另类刺激| 婷婷综合网站| 欧美男人的天堂| 欧美影院精品| 国产精品观看在线亚洲人成网 | 亚洲高清免费| 久久久在线视频| 成人欧美亚洲| 欧美精品一区二区久久婷婷| 中文字幕欧美在线观看| 亚洲成人综合视频| 日本二区三区视频| 久久久综合视频| 亚洲欧洲国产视频| 久久精品免费观看| 国产日韩一区二区在线| 欧美区一区二| 亚洲伊人婷婷| 亚洲免费大片在线观看| 中文字幕一区二区三区四区五区人 | 国产模特av私拍大尺度| 粉嫩av一区二区三区免费野| 手机在线免费看毛片| 久久久99精品免费观看不卡| www.黄色网| 国产一区二区调教| 日本美女高潮视频| 奶水喷射视频一区| 日韩国产成人无码av毛片| 日韩欧美视频专区| 欧美一区观看| 蜜桃精品wwwmitaows| 精品国产中文字幕| 2023国产精华国产精品| 亚洲iv一区二区三区| 成人免费在线观看视频| 日韩美女中文字幕| 美女露胸视频在线观看| 国产综合在线视频| 欧美wwww| 欧美激情一级欧美精品| 性欧美1819sex性高清大胸| 中文字幕精品网| 午夜在线视频播放| 日韩精品免费一区二区三区| 亚洲视频欧美视频| 日韩精品一二| 日韩精品在线电影| 天堂а√在线8种子蜜桃视频| 亚洲а∨天堂久久精品9966| 国产 欧美 自拍| 亚洲成人久久久| 亚洲精品综合网| 精品国产乱码久久久久久夜甘婷婷 | 岛国精品在线播放| 日本天堂在线播放| 成人app下载| 无遮挡aaaaa大片免费看| 91美女在线视频| 一道本在线观看| 中文成人综合网| 久草福利资源在线| 亚洲精品日韩一| 国产亚洲精品久久777777| 欧美日韩国产综合视频在线观看中文| 日韩精品一区二区三| 日韩欧美中文字幕在线观看 | 欧美日本一区二区| 国产免费一区二区三区最新不卡| 日韩精品专区在线影院重磅| 粉嫩av一区二区夜夜嗨| 日韩成人在线视频观看| 国产在线色视频| 日日骚av一区| 欧美日韩在线视频免费观看| 国内伊人久久久久久网站视频 | www.成人爱| 国产日韩欧美黄色| 大香伊人久久精品一区二区| 久久偷窥视频| 99精品美女| 欧美三级在线观看视频| 日韩精品亚洲一区| 樱花草www在线| 97aⅴ精品视频一二三区| 精品播放一区二区| 激情小视频在线| 久久中文字幕在线| 在线观看免费高清视频| 激情欧美丁香| 人妻无码视频一区二区三区| 国内精品自线一区二区三区视频| 丰满人妻一区二区三区免费视频棣| 久久久亚洲精品石原莉奈| 精品无码一区二区三区蜜臀| 精品国产乱码久久久久久天美| 色婷婷久久综合中文久久蜜桃av| 日韩欧美不卡一区| 国产在线高清| 色综合91久久精品中文字幕| 日韩av超清在线观看| 99久久综合狠狠综合久久止| 精品国产91| 成品人视频ww入口| 精东粉嫩av免费一区二区三区| 在线视频 日韩| 综合欧美一区二区三区| 日本视频在线观看免费| 日韩一区二区三区精品视频 | av中文字幕不卡| 我家有个日本女人| 在线观看日韩电影| 日本黄色一区二区三区| 日韩av影院在线观看| 在线免费观看污| 国产有码在线一区二区视频| 美女视频免费精品| av动漫在线免费观看| 麻豆成人在线观看| mm131美女视频| 午夜电影一区二区| 99在线小视频| 最近中文字幕mv在线一区二区三区四区| 国产伦理精品| 国产经典一区二区三区| 国产精品成久久久久| 四季av一区二区| 26uuu色噜噜精品一区| 精品无码人妻一区二区三| 3d动漫精品啪啪1区2区免费| a天堂中文在线| 国产精品爱啪在线线免费观看| 91精品短视频| av在线com| 国产成人在线免费| 日本老熟俱乐部h0930| 91超碰这里只有精品国产| 国产露出视频在线观看| 日本一区二区在线播放| 老司机精品视频在线播放| 国产黄色片免费在线观看| 国产成人在线免费| 久久久久久久福利| 日韩欧美亚洲另类制服综合在线| a视频在线观看| 1卡2卡3卡精品视频| 亚洲自拍偷拍网| 青娱乐国产精品视频| 亚洲欧洲在线观看av| 国产精品亚洲lv粉色| 久久九九免费视频| 国产精品毛片aⅴ一区二区三区| 国产系列第一页| 国产精品一区二区无线| 久久久久性色av无码一区二区| 日韩欧美三级在线| 丰满大乳少妇在线观看网站| 国产精华一区二区三区| 亚洲免费观看| www.久久国产| 欧美网站一区二区| 免费a级在线播放| 国产主播欧美精品| 一区二区日韩欧美| 蜜桃色一区二区三区| 精品成人在线视频| 美丽的姑娘在线观看免费动漫| 国产精品va在线播放| 久久影视一区| 久久精品一二三四| 欧美日韩国产精品专区 | 国产精品色在线网站| 欧美一区二区三区爽大粗免费| 久久嫩草精品久久久久| 中文字幕在线2019| 欧美成人在线免费| 欧美三级午夜理伦三级小说| 免费日韩视频在线观看| 国产精品色婷婷久久58| 国产999久久久| 欧美自拍大量在线观看| 欧洲grand老妇人| 中文字幕资源在线观看| 亚洲国产aⅴ成人精品无吗| 久青青在线观看视频国产| 国产日产欧美精品| 亚洲三级色网| 女教师淫辱の教室蜜臀av软件| 日韩欧美不卡在线观看视频| 欧美大胆性生话| 中国老女人av| 久久久午夜精品理论片中文字幕| 国产精品无码天天爽视频| 91精品国产91久久久| 色综合五月天| 日韩av无码一区二区三区不卡| 欧美亚洲国产一区在线观看网站| 亚洲区欧洲区| 五月天久久狠狠| 成人免费视频视频在线观看免费| 伊人久久久久久久久久久久| 欧美精品午夜视频| 精品国产一区一区二区三亚瑟| 少妇极品熟妇人妻无码| 91黄色免费观看| 成人免费观看在线观看| 手机成人av在线| 久久久电影一区二区三区|