深入理解JS中的Promise.race控制并發(fā)量
開篇
比如在開發(fā)中會(huì)進(jìn)行一系列的網(wǎng)絡(luò)請(qǐng)求,但是有些情況需要控制一下網(wǎng)絡(luò)請(qǐng)求請(qǐng)并發(fā)量。這里簡(jiǎn)單的用 Promise.race 及 await 的特性來理解一下,如何對(duì)任務(wù)的并發(fā)量進(jìn)行控制。
一、Promise.race
Promise.race 作用就是將多個(gè)異步任務(wù)包裹起來,當(dāng)有一個(gè)完成的話,那么就會(huì)觸發(fā) then 事件。除了這個(gè)不錯(cuò)的特性方法外,await 這個(gè)關(guān)鍵字也比較有用,可以這樣理解,await 后面的代碼其實(shí)就相當(dāng)于在 Promise 的 then 事件,即:如果異步任務(wù)沒有完成的話,await 后面的邏輯是不會(huì)執(zhí)行的,可以聯(lián)想一下 generator 生成器里面的 yield 它能直接控制方法體里面的代碼執(zhí)行跟暫停,外界由一個(gè)迭代器 next 方法進(jìn)行操控。
await 雖然好用,也只是在一個(gè)“異步”方法里需要“同步執(zhí)行”的時(shí)候。then 的異步回調(diào),其實(shí)也有它的用處??梢詫⑼耆魂P(guān)心的事務(wù)放到里面,由它去執(zhí)行到最后的結(jié)果。
二、并發(fā)效果展示
三、代碼
class ConcurrencyTask { // 回調(diào) callBack = ()=>{} // 任務(wù) task = ()=>{} // 異步任務(wù) promse = null constructor(task,callBack){ this.task = task this.callBack = callBack } // 開始進(jìn)行任務(wù) beginExecuteTask(){ this.promse = new Promise((resolve, reject)=>{ this.task(resolve,reject) }) return this.promse } // 類方法初始化 static SimulationTask(time){ return new ConcurrencyTask((resolve, _)=>{ console.log('開始執(zhí)行延時(shí)任務(wù):' + (time / 1000) + '秒!') setTimeout(()=>{ resolve('延時(shí)任務(wù)完成:' + (time / 1000) + '秒!') },time) },(res)=>{ console.log(res) }) } } class ConcurrencyQueue { // 最大并發(fā)數(shù) maxConcurrencyNum = 1 // 并發(fā)任務(wù)集合 concurrencyTasks = [] // 正在進(jìn)行的任務(wù) executionTasks = [] constructor(maxConcurrencyNum,...concurrencyTasks){ this.maxConcurrencyNum = maxConcurrencyNum concurrencyTasks.forEach((task)=>{ this.concurrencyTasks.push(task) }) } // 開始執(zhí)行 async beginExecuteTasks(){ // 當(dāng)前執(zhí)行任務(wù) this.executionTasks = [] // 全部任務(wù) let allExecutionTasks = [] for(let index = 0;index < this.concurrencyTasks.length;index ++){ let task = this.concurrencyTasks[index] // 開始并進(jìn)行后續(xù)追蹤 task.beginExecuteTask().then((res)=>{ this.executionTasks.splice(this.executionTasks.indexOf(task),1) if(task.callBack){ task.callBack(res) } }) // 不足直接添加 if(this.executionTasks.length < this.maxConcurrencyNum){ //待執(zhí)行任務(wù)集合添加 this.executionTasks.push(task) //全任務(wù)執(zhí)行集合添加 allExecutionTasks.push(task) if((this.concurrencyTasks.length - 1) == index || this.executionTasks.length >= this.maxConcurrencyNum){ // 滿足直接運(yùn)行 await Promise.race(this.executionTasks.map((task)=>{ return task.promse })) } } } //全部任務(wù)完成 await Promise.all(allExecutionTasks.map((task)=>{ return task.promse })) console.log('任務(wù)全部完成') } } export { ConcurrencyTask ,ConcurrencyQueue }
ESM 模式導(dǎo)入,需要 node 簡(jiǎn)單起一個(gè)服務(wù)
<script type="module"> import { ConcurrencyTask ,ConcurrencyQueue } from "./concurrencyTask.js" //添加任務(wù) let concurrencyQueue = new ConcurrencyQueue(3,ConcurrencyTask.SimulationTask(1000),ConcurrencyTask.SimulationTask(6000),ConcurrencyTask.SimulationTask(5000),ConcurrencyTask.SimulationTask(4000),ConcurrencyTask.SimulationTask(2000),ConcurrencyTask.SimulationTask(3000)) //開始執(zhí)行任務(wù) concurrencyQueue.beginExecuteTasks() </script>
總結(jié)與思考
如果知識(shí)點(diǎn)不能結(jié)合應(yīng)用場(chǎng)景,那么,它其實(shí)沒有什么需要記憶的必要性。
以上就是深入理解JS中的Promise.race控制并發(fā)量的詳細(xì)內(nèi)容,更多關(guān)于JS Promise.race 控制并發(fā)量的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于jquery實(shí)現(xiàn)的省市區(qū)級(jí)聯(lián)無ajax
省市區(qū)級(jí)聯(lián)的實(shí)現(xiàn)方法有很多,在本文為大家介紹下如何使用jquery無ajax來實(shí)現(xiàn),感興趣的朋友可以參考下,希望對(duì)大家有所幫助2013-09-09JavaScript獲取當(dāng)前url根目錄(路徑)
本文主要介紹JavaScript獲取當(dāng)前url根目錄的方法,比較實(shí)用,需要的朋友可以參考一下。2016-06-06JS中實(shí)現(xiàn)簡(jiǎn)單Formatter函數(shù)示例代碼
JS沒有提供方便使用的Formatter函數(shù),用字符拼接的方式看起來混亂難讀,下面是JS簡(jiǎn)單實(shí)現(xiàn)版本(沒有嚴(yán)格測(cè)試)2014-08-08js通過location.search來獲取頁(yè)面?zhèn)鱽淼膮?shù)
js獲取通過window.location.search來獲取頁(yè)面?zhèn)鱽淼膮?shù),經(jīng)測(cè)試可用,大家可以學(xué)習(xí)下2014-09-09現(xiàn)代配置YAML對(duì)比JSON優(yōu)勢(shì)分析
這篇文章主要為大家介紹了關(guān)于現(xiàn)代配置指南中YAML對(duì)比JSON的優(yōu)勢(shì)分析說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02基于aotu.js實(shí)現(xiàn)微信自動(dòng)添加通訊錄中的聯(lián)系人功能
這篇文章主要介紹了利用aotu.js實(shí)現(xiàn)微信自動(dòng)添加通訊錄中的聯(lián)系人,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05JavaScript中函數(shù)聲明與函數(shù)表達(dá)式的區(qū)別詳解
可能很多朋友只知道兩種聲明方式一個(gè)是函數(shù)聲明一個(gè)是函數(shù)表達(dá)式,具體有什么不同沒能說得很好。事實(shí)上,JavaScript的解析器對(duì)函數(shù)聲明與函數(shù)表達(dá)式并不是一視同仁地對(duì)待的。下面看看這兩者到底有什么不同。2016-08-08