深入理解JS中的Promise.race控制并發(fā)量
開篇
比如在開發(fā)中會進(jìn)行一系列的網(wǎng)絡(luò)請求,但是有些情況需要控制一下網(wǎng)絡(luò)請求請并發(fā)量。這里簡單的用 Promise.race 及 await 的特性來理解一下,如何對任務(wù)的并發(fā)量進(jìn)行控制。
一、Promise.race
Promise.race 作用就是將多個異步任務(wù)包裹起來,當(dāng)有一個完成的話,那么就會觸發(fā) then 事件。除了這個不錯的特性方法外,await 這個關(guān)鍵字也比較有用,可以這樣理解,await 后面的代碼其實(shí)就相當(dāng)于在 Promise 的 then 事件,即:如果異步任務(wù)沒有完成的話,await 后面的邏輯是不會執(zhí)行的,可以聯(lián)想一下 generator 生成器里面的 yield 它能直接控制方法體里面的代碼執(zhí)行跟暫停,外界由一個迭代器 next 方法進(jìn)行操控。
await 雖然好用,也只是在一個“異步”方法里需要“同步執(zhí)行”的時候。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í)行延時任務(wù):' + (time / 1000) + '秒!')
setTimeout(()=>{
resolve('延時任務(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 簡單起一個服務(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é)與思考
如果知識點(diǎn)不能結(jié)合應(yīng)用場景,那么,它其實(shí)沒有什么需要記憶的必要性。
以上就是深入理解JS中的Promise.race控制并發(fā)量的詳細(xì)內(nèi)容,更多關(guān)于JS Promise.race 控制并發(fā)量的資料請關(guān)注腳本之家其它相關(guān)文章!
- 微信小程序 es6-promise.js封裝請求與處理異步進(jìn)程
- 基于promise.js實(shí)現(xiàn)nodejs的promises庫
- Javascript?promise.all的用法介紹(簡潔易懂)
- 在JavaScript中使用Promise.allSettled()的方法
- JavaScript 中使用Promise.all()方法經(jīng)驗(yàn)技巧詳解
- JavaScript中promise.all和promise.race的區(qū)別詳解
- 深入理解JS中?Promise.all?和?Promise.allSettled?特性和區(qū)別應(yīng)用場景分析
- JavaScript Promise.all 靜態(tài)方法常見問題記錄
- JS中Promise.all 與 Promise.race的區(qū)別小結(jié)
- JavaScript中Promise.try() 的用法小結(jié)
相關(guān)文章
javascript動態(tài)設(shè)置樣式style實(shí)例分析
這篇文章主要介紹了javascript動態(tài)設(shè)置樣式style的方法,實(shí)例分析了javascript操作style樣式的易錯點(diǎn)和相關(guān)使用技巧,需要的朋友可以參考下2015-05-05
Uniapp?WebView全屏導(dǎo)致遮擋狀態(tài)欄的解決方案及注意事項(xiàng)
這篇文章主要介紹了Uniapp?WebView全屏導(dǎo)致遮擋狀態(tài)欄的解決方案及注意事項(xiàng),通過動態(tài)調(diào)整WebView的布局,確保狀態(tài)欄可見,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-05-05
原生js實(shí)現(xiàn)寬度計(jì)數(shù)器
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)寬度計(jì)數(shù)器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-09-09
javascript算法之?dāng)?shù)組反轉(zhuǎn)
這篇文章主要介紹了javascript算法之?dāng)?shù)組反轉(zhuǎn),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08

