深入理解JS中的Promise.race控制并發(fā)量
開篇
比如在開發(fā)中會進行一系列的網(wǎng)絡請求,但是有些情況需要控制一下網(wǎng)絡請求請并發(fā)量。這里簡單的用 Promise.race 及 await 的特性來理解一下,如何對任務的并發(fā)量進行控制。
一、Promise.race
Promise.race 作用就是將多個異步任務包裹起來,當有一個完成的話,那么就會觸發(fā) then 事件。除了這個不錯的特性方法外,await 這個關鍵字也比較有用,可以這樣理解,await 后面的代碼其實就相當于在 Promise 的 then 事件,即:如果異步任務沒有完成的話,await 后面的邏輯是不會執(zhí)行的,可以聯(lián)想一下 generator 生成器里面的 yield 它能直接控制方法體里面的代碼執(zhí)行跟暫停,外界由一個迭代器 next 方法進行操控。
await 雖然好用,也只是在一個“異步”方法里需要“同步執(zhí)行”的時候。then 的異步回調,其實也有它的用處??梢詫⑼耆魂P心的事務放到里面,由它去執(zhí)行到最后的結果。
二、并發(fā)效果展示

三、代碼
class ConcurrencyTask {
// 回調
callBack = ()=>{}
// 任務
task = ()=>{}
// 異步任務
promse = null
constructor(task,callBack){
this.task = task
this.callBack = callBack
}
// 開始進行任務
beginExecuteTask(){
this.promse = new Promise((resolve, reject)=>{
this.task(resolve,reject)
})
return this.promse
}
// 類方法初始化
static SimulationTask(time){
return new ConcurrencyTask((resolve, _)=>{
console.log('開始執(zhí)行延時任務:' + (time / 1000) + '秒!')
setTimeout(()=>{
resolve('延時任務完成:' + (time / 1000) + '秒!')
},time)
},(res)=>{
console.log(res)
})
}
}
class ConcurrencyQueue {
// 最大并發(fā)數(shù)
maxConcurrencyNum = 1
// 并發(fā)任務集合
concurrencyTasks = []
// 正在進行的任務
executionTasks = []
constructor(maxConcurrencyNum,...concurrencyTasks){
this.maxConcurrencyNum = maxConcurrencyNum
concurrencyTasks.forEach((task)=>{
this.concurrencyTasks.push(task)
})
}
// 開始執(zhí)行
async beginExecuteTasks(){
// 當前執(zhí)行任務
this.executionTasks = []
// 全部任務
let allExecutionTasks = []
for(let index = 0;index < this.concurrencyTasks.length;index ++){
let task = this.concurrencyTasks[index]
// 開始并進行后續(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í)行任務集合添加
this.executionTasks.push(task)
//全任務執(zhí)行集合添加
allExecutionTasks.push(task)
if((this.concurrencyTasks.length - 1) == index || this.executionTasks.length >= this.maxConcurrencyNum){
// 滿足直接運行
await Promise.race(this.executionTasks.map((task)=>{ return task.promse }))
}
}
}
//全部任務完成
await Promise.all(allExecutionTasks.map((task)=>{ return task.promse }))
console.log('任務全部完成')
}
}
export { ConcurrencyTask ,ConcurrencyQueue }
ESM 模式導入,需要 node 簡單起一個服務
<script type="module">
import { ConcurrencyTask ,ConcurrencyQueue } from "./concurrencyTask.js"
//添加任務
let concurrencyQueue = new ConcurrencyQueue(3,ConcurrencyTask.SimulationTask(1000),ConcurrencyTask.SimulationTask(6000),ConcurrencyTask.SimulationTask(5000),ConcurrencyTask.SimulationTask(4000),ConcurrencyTask.SimulationTask(2000),ConcurrencyTask.SimulationTask(3000))
//開始執(zhí)行任務
concurrencyQueue.beginExecuteTasks()
</script>
總結與思考
如果知識點不能結合應用場景,那么,它其實沒有什么需要記憶的必要性。
以上就是深入理解JS中的Promise.race控制并發(fā)量的詳細內容,更多關于JS Promise.race 控制并發(fā)量的資料請關注腳本之家其它相關文章!
相關文章
基于jquery實現(xiàn)的省市區(qū)級聯(lián)無ajax
省市區(qū)級聯(lián)的實現(xiàn)方法有很多,在本文為大家介紹下如何使用jquery無ajax來實現(xiàn),感興趣的朋友可以參考下,希望對大家有所幫助2013-09-09
JS中實現(xiàn)簡單Formatter函數(shù)示例代碼
JS沒有提供方便使用的Formatter函數(shù),用字符拼接的方式看起來混亂難讀,下面是JS簡單實現(xiàn)版本(沒有嚴格測試)2014-08-08
js通過location.search來獲取頁面?zhèn)鱽淼膮?shù)
js獲取通過window.location.search來獲取頁面?zhèn)鱽淼膮?shù),經(jīng)測試可用,大家可以學習下2014-09-09
基于aotu.js實現(xiàn)微信自動添加通訊錄中的聯(lián)系人功能
這篇文章主要介紹了利用aotu.js實現(xiàn)微信自動添加通訊錄中的聯(lián)系人,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
JavaScript中函數(shù)聲明與函數(shù)表達式的區(qū)別詳解
可能很多朋友只知道兩種聲明方式一個是函數(shù)聲明一個是函數(shù)表達式,具體有什么不同沒能說得很好。事實上,JavaScript的解析器對函數(shù)聲明與函數(shù)表達式并不是一視同仁地對待的。下面看看這兩者到底有什么不同。2016-08-08

