亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript實現(xiàn)帶并發(fā)限制的異步調(diào)度器

 更新時間:2024年03月26日 09:09:59   作者:翰玥  
這篇文章主要為大家詳細介紹了如何基于JS實現(xiàn)一個帶并發(fā)限制的異步調(diào)度器?Scheduler,保證同時運行的任務最多有N個,感興趣的小伙伴可以了解下

題目

實現(xiàn)一個帶并發(fā)限制的異步調(diào)度器 Scheduler,保證同時運行的任務最多有N個。完善下面代碼中的Scheduler類,使得以下程序能正確輸出:

class Scheduler {
  add(promiseCreator) { ... }
  // ...
}

const timeout = (time) => new Promise(resolve => {
  setTimeout(resolve, time)
})

const scheduler = new Scheduler(n)
const addTask = (time, order) => {
  scheduler.add(() => timeout(time)).then(() => console.log(order))
}

addTask(1000, '1')  // 任務1
addTask(500, '2') // 任務2
addTask(300, '3') // 任務3
addTask(400, '4')  // 任務4

// 打印順序是:2 3 1 4

題目分析

假設N為2,也就是保證同時運行的任務有2個。那么在執(zhí)行addTask 4步操作之后,整體的流程應該是這樣的。

  • 起始1、2兩個任務開始執(zhí)行;
  • 500ms時,2任務執(zhí)行完畢,輸出2,任務3開始執(zhí)行;
  • 800ms時,3任務執(zhí)行完畢,輸出3,任務4開始執(zhí)行;
  • 1000ms時,1任務執(zhí)行完畢,輸出1,此時只剩下4任務在執(zhí)行;
  • 1200ms時,4任務執(zhí)行完畢,輸出4;

為什么會出現(xiàn)這樣的結果?我們來具體分析一下

首先連續(xù)執(zhí)行了4次addTask,由于只能同時運行的任務有2個,所以,任務1和任務2將直接運行,任務1將在1000ms之后運行,任務2將在500ms之后運行,所以,任務2肯定會比任務1執(zhí)行的快。當任務2執(zhí)行完畢之后,輸出2。緊接著執(zhí)行任務3,此時任務1執(zhí)行也就經(jīng)過了500ms,還有500ms沒有執(zhí)行完,而任務3只需要300ms就執(zhí)行完畢,所以任務3也會比任務1執(zhí)行的快。又過了300ms(共計過了800ms)任務3執(zhí)行完畢,輸出3。任務4開始執(zhí)行,任務4需要400ms執(zhí)行完畢,而任務1目前只需要200ms,所以任務1會比任務4先執(zhí)行,200ms之后(共計1000ms)任務1執(zhí)行完畢,輸出1,在過了200ms(共計1200ms),任務4執(zhí)行完畢,輸出4。

下面我們用圖來表示一下

知道了這道題目具體要干啥了,下面就來看看代碼是如何實現(xiàn)的

代碼實現(xiàn)

直接上完整代碼好了~

class Scheduler {
  constructor(max) {
    this.max = max;
    this.count = 0; // 用來記錄當前正在執(zhí)行的異步函數(shù)
    this.queue = new Array(); // 表示等待隊列
  }
  async add(promiseCreator) {
    /*
        此時count已經(jīng)滿了,不能執(zhí)行本次add需要阻塞在這里,將resolve放入隊列中等待喚醒,
        等到count<max時,從隊列中取出執(zhí)行resolve,執(zhí)行,await執(zhí)行完畢,本次add繼續(xù)
        */
    if (this.count >= this.max) {
      await new Promise((resolve, reject) => this.queue.push(resolve));
    }

    this.count++;
    let res = await promiseCreator();
    this.count--;
    if (this.queue.length) {
      // 依次喚醒add
      // 若隊列中有值,將其resolve彈出,并執(zhí)行
      // 以便阻塞的任務,可以正常執(zhí)行
      this.queue.shift()();
    }
    return res;
  }
}

const timeout = time =>
  new Promise(resolve => {
    setTimeout(resolve, time);
  });

const scheduler = new Scheduler(2);

const addTask = (time, order) => {
  //add返回一個promise,參數(shù)也是一個promise
  scheduler.add(() => timeout(time)).then(() => console.log(order));
};
  
  addTask(1000, '1');
  addTask(500, '2');
  addTask(300, '3');
  addTask(400, '4');
  
// output: 2 3 1 4

這塊代碼中我們主要加了add部分。

首先我們來分析一下 Scheduler這個類。max表示同時可以執(zhí)行任務的最大數(shù)量。count用來記錄當前正在執(zhí)行的異步函數(shù)。每次addTask都會通過scheduler.add添加一個異步任務。

進入add函數(shù)中,首先需要做的事情是當前已經(jīng)正在執(zhí)行的任務有沒有到達最大的任務數(shù)。

如果沒有達到最大的任務數(shù)(比如剛開始的加入任務一和任務二,此時任務是空的),每次執(zhí)行await promiseCreator();這一步的時候,使用async await,當promiseCreator沒有執(zhí)行完畢的時候,會阻塞后面的任務。所以當前兩個任務被addTask加入的時候,執(zhí)行add的時候,都會阻塞后面的任務。而我們的四個任務連續(xù)被加入的。當add任務三和任務四的時候,發(fā)現(xiàn)此時count已經(jīng)滿了,所以需要阻塞在這里,將resolve放入隊列中等待喚醒嗎,具體什么時候被喚醒呢?,當前面的任務有任何一個執(zhí)行完畢之后,就可以被喚醒。這里使用queue來維護resolve,add任務三和任務四的時候,會先后給queue推入這兩個promiseresolve。

經(jīng)過500ms,任務二會先執(zhí)行完畢,也就是await promiseCreator();執(zhí)行完畢之后,打印2,然后繼續(xù)之后后續(xù)的代碼,此時從queue里面將第一個resolve彈出,并執(zhí)行。執(zhí)行之后,任務3也就不再阻塞了,將繼續(xù)執(zhí)行await promiseCreator();.

再經(jīng)過300ms任務三先執(zhí)行完畢之后(任務還在繼續(xù)執(zhí)行中),打印3,然后繼續(xù)之后后續(xù)的代碼,此時從queue里面將resolve彈出,并執(zhí)行。執(zhí)行之后,任務4也就不再阻塞了,將繼續(xù)執(zhí)行await promiseCreator();.

再經(jīng)過200ms任務一終于執(zhí)行完畢之后,打印1,然后繼續(xù)之后后續(xù)的代碼,此時queue里面已經(jīng)是空的了

再經(jīng)過200ms任務四執(zhí)行完畢,打印4

到此這篇關于JavaScript實現(xiàn)帶并發(fā)限制的異步調(diào)度器的文章就介紹到這了,更多相關JavaScript異步調(diào)度器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Javascript 判斷 object 的特定類轉(zhuǎn)載

    Javascript 判斷 object 的特定類轉(zhuǎn)載

    Javascript 判斷 object 的特定類轉(zhuǎn)載...
    2007-02-02
  • Google Map API更新實現(xiàn)用戶自定義標注坐標

    Google Map API更新實現(xiàn)用戶自定義標注坐標

    由于工作需要,又要開始看Google Map API 代碼,今天再把我之前的GoogleMap類,又更新了下,加了個簡單的用戶自定義標注坐標的功能??纯窗?代碼沒怎么優(yōu)化,別見笑)
    2009-07-07
  • js事件監(jiān)聽器用法實例詳解

    js事件監(jiān)聽器用法實例詳解

    這篇文章主要介紹了js事件監(jiān)聽器用法,以實例形式較為詳細的分析了javascript事件監(jiān)聽器使用注意事項與相關技巧,需要的朋友可以參考下
    2015-06-06
  • Bootstrap popover 實現(xiàn)鼠標移入移除顯示隱藏功能方法

    Bootstrap popover 實現(xiàn)鼠標移入移除顯示隱藏功能方法

    下面小編就為大家分享一篇Bootstrap popover 實現(xiàn)鼠標移入移除顯示隱藏功能方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • php的派發(fā)機制實現(xiàn)方法

    php的派發(fā)機制實現(xiàn)方法

    PHP是一種動態(tài)類型的編程語言,它支持面向?qū)ο缶幊?在PHP中,派發(fā)指在運行時確定要調(diào)用的方法或函數(shù)的過程,派發(fā)機制允許根據(jù)實際對象的類型來選擇要執(zhí)行的方法,這種靈活性使得PHP可以實現(xiàn)多態(tài)性,本文將給大家介紹php的派發(fā)機制是怎么實現(xiàn)的,需要的朋友可以參考下
    2023-10-10
  • 淺談JavaScript原型鏈

    淺談JavaScript原型鏈

    這篇文章主要為大家詳細介紹了JavaScript原型鏈,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2023-04-04
  • DeviceOne 讓你一見鐘情的App快速開發(fā)平臺

    DeviceOne 讓你一見鐘情的App快速開發(fā)平臺

    DeviceOne是一個非常先進的App開發(fā)平臺,使用Javascript 構建原生體驗的移動應用程序,DeviceOne主要關注外觀和體驗,以及和你的應用程序的 UI 交互
    2016-02-02
  • Bootstrap中表單控件狀態(tài)(驗證狀態(tài))

    Bootstrap中表單控件狀態(tài)(驗證狀態(tài))

    這篇文章主要介紹了Bootstrap中表單控件狀態(tài)(驗證狀態(tài)) 的相關資料,還給大家介紹了在Bootstrap框架中提供的機制驗證效果,非常不錯,需要的朋友可以參考下
    2016-08-08
  • Bootstrap CSS布局之按鈕

    Bootstrap CSS布局之按鈕

    這篇文章主要介為大家詳細紹了Bootstrap CSS布局之按鈕的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • JavaScript實現(xiàn)動態(tài)創(chuàng)建CSS樣式規(guī)則方案

    JavaScript實現(xiàn)動態(tài)創(chuàng)建CSS樣式規(guī)則方案

    這篇文章主要介紹了JavaScript實現(xiàn)動態(tài)創(chuàng)建CSS樣式規(guī)則方案,本文包含獲取樣式表、創(chuàng)建樣式表、插入規(guī)則、添加規(guī)則等內(nèi)容,需要的朋友可以參考下
    2014-09-09

最新評論