基于JS實(shí)現(xiàn)帶并發(fā)限制的異步調(diào)度器
題目描述
JS實(shí)現(xiàn)一個(gè)帶并發(fā)限制的異步調(diào)度器scheduler,保證同時(shí)運(yùn)行的任務(wù)最多有兩個(gè)。
例如目前有4個(gè)任務(wù),完成時(shí)間分別為,1000ms,500ms,300ms,400ms
那么在該調(diào)度器中的執(zhí)行完成順序應(yīng)該為2、3、1、4.
因?yàn)?、2先進(jìn)入隊(duì)列中,2完成則輸出2,3進(jìn)入,3完成輸出3,此時(shí)為800ms,4進(jìn)入后的200ms,1完成輸出1,而后4完成輸出4.
實(shí)現(xiàn)最多兩個(gè)任務(wù)同時(shí)運(yùn)行。
代碼調(diào)用模板大概是:
class Scheduler{
add(promiseCreator){.....}
}
// 設(shè)置一個(gè)以每time秒執(zhí)行異步任務(wù)的定時(shí)器
const timeout = (time) => {
new Promise(resolve => {
setTimeout(resolve,time)
})
}
// 實(shí)例
const scheduler = new Scheduler()
const addTask = (time,order)=>{
scheduler.add(()=>{ //調(diào)用實(shí)例的方法
timeout(time) //每time秒執(zhí)行一下任務(wù)(其實(shí)每一秒就行->time=1000ms即可)
})
}emmmmm我先來分析下....剛看這題有點(diǎn)懵,
通俗點(diǎn):有個(gè)只能同時(shí)執(zhí)行倆任務(wù)的隊(duì)列,正在以每time秒執(zhí)行這些任務(wù),且任務(wù)按照順序進(jìn)入隊(duì)列。
那,同時(shí)運(yùn)行的任務(wù)不能超過兩個(gè),是不是每次運(yùn)行一個(gè)任務(wù)時(shí)就放進(jìn)數(shù)組中,判斷任務(wù)的length是否小于2,在大于0且小于2的情況下就即刻執(zhí)行該promise函數(shù)。
欸嘿,那運(yùn)行兩個(gè)任務(wù)的時(shí)候怎么辦?要對(duì)promise函數(shù)進(jìn)行一個(gè)選型,不能用一般的promise.then咯,在這同時(shí)運(yùn)行的兩個(gè)任務(wù)中需要有一個(gè)先后判斷,哪個(gè)先執(zhí)行完,需要下一個(gè)任務(wù)接替執(zhí)行的,所以這當(dāng)中存在一個(gè)“競賽”關(guān)系,選擇使用promise.race咯。(ps:這倆任務(wù)給我卷起來?。。。。?/p>
確認(rèn)一下捏,有一個(gè)任務(wù)在隊(duì)列中的情況時(shí),只需要執(zhí)行該任務(wù),and執(zhí)行完從隊(duì)列中刪除就好了。
but有兩個(gè)的時(shí)候就要判斷遼,只要隊(duì)列中的size等于/大于2,就要進(jìn)行promise.race的賽跑執(zhí)行,finally執(zhí)行完再去add下一個(gè)(promise任務(wù))進(jìn)來接著卷~。
就醬紫,寫代碼叭~
class Scheduler{
queue = new Set<Promise<any>>() //去重的promise隊(duì)列~
add(promiseCreator:()=>Promose<any>){ //每次用來加任務(wù)的方法~~
if(this.queue.size>0 && this.queue.size<2){
const promise = promiseCreator()
this.queue.add(promise)
promise.finally(()=>{
this.queue.delete(promise)
})
return promise
}
// 只要到了2個(gè)任務(wù) 就開始race這倆任務(wù)
// race出個(gè)結(jié)果再繼續(xù)放下一個(gè)(doge)卷起來
const queueArr = []
this.queue.forEach(item => queueArr.push(item)) // 放進(jìn)數(shù)組中~
return Promise.race(queueArr).finally(this.add(promiseCreator))
}
}get!,最后再調(diào)用下可以查看結(jié)果啦。
addTask(1000,1)
addTask(500,2)
addTask(300,3)
addTask(400,4)
快看看是不是2、3、1、4叭~
到此這篇關(guān)于基于JS實(shí)現(xiàn)帶并發(fā)限制的異步調(diào)度器的文章就介紹到這了,更多相關(guān)JS異步調(diào)度器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript contains和compareDocumentPosition 方法來確定是否HTML節(jié)點(diǎn)間的關(guān)
一個(gè)很棒的 blog 文章,是 PPK 兩年前寫的,文章中解釋了 contains() 和 compareDocumentPosition() 方法運(yùn)行在他們各自的瀏覽器上。2010-02-02
jQuery Mobile動(dòng)態(tài)刷新頁面樣式的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猨Query Mobile動(dòng)態(tài)刷新頁面樣式的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05
Javascript獲取與設(shè)置ckeditor數(shù)據(jù)的實(shí)現(xiàn)方法
最近編輯器后臺(tái)升級(jí)成了ckeditor,但原來后臺(tái)有很多對(duì)應(yīng)編輯器內(nèi)容的替換功能,那么就需要用js獲取ckeditor編輯器里面的內(nèi)容,這里就為大家介紹一下具體的實(shí)現(xiàn)方法2023-08-08
JavaScript函數(shù)及其prototype詳解
這篇文章主要介紹了JavaScript函數(shù)及其prototype詳解的相關(guān)資料,需要的朋友可以參考下2023-03-03
uniapp使用uni-file-picker實(shí)現(xiàn)上傳功能
這篇文章主要介紹了uniapp使用uni-file-picker實(shí)現(xiàn)上傳功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-07-07
基于iScroll實(shí)現(xiàn)下拉刷新和上滑加載效果
這篇文章主要為大家詳細(xì)介紹了基于iScroll實(shí)現(xiàn)下拉刷新和上滑加載效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
javascript實(shí)現(xiàn)table單元格點(diǎn)擊展開隱藏效果(實(shí)例代碼)
這篇文章主要介紹了javascript實(shí)現(xiàn)table單元格點(diǎn)擊展開隱藏效果的實(shí)例代碼講解,代碼簡單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-04-04
用jquery.sortElements實(shí)現(xiàn)table排序
實(shí)現(xiàn)table排序,網(wǎng)上有很多解決方案,很多都基于jQuery,最后我選擇用sortElements,實(shí)現(xiàn)很簡單2014-05-05

