最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

題目

實(shí)現(xiàn)一個(gè)帶并發(fā)限制的異步調(diào)度器 Scheduler,保證同時(shí)運(yùn)行的任務(wù)最多有N個(gè)。完善下面代碼中的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')  // 任務(wù)1
addTask(500, '2') // 任務(wù)2
addTask(300, '3') // 任務(wù)3
addTask(400, '4')  // 任務(wù)4

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

題目分析

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

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

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

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

下面我們用圖來表示一下

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

代碼實(shí)現(xiàn)

直接上完整代碼好了~

class Scheduler {
  constructor(max) {
    this.max = max;
    this.count = 0; // 用來記錄當(dāng)前正在執(zhí)行的異步函數(shù)
    this.queue = new Array(); // 表示等待隊(duì)列
  }
  async add(promiseCreator) {
    /*
        此時(shí)count已經(jīng)滿了,不能執(zhí)行本次add需要阻塞在這里,將resolve放入隊(duì)列中等待喚醒,
        等到count<max時(shí),從隊(duì)列中取出執(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) {
      // 依次喚醒a(bǔ)dd
      // 若隊(duì)列中有值,將其resolve彈出,并執(zhí)行
      // 以便阻塞的任務(wù),可以正常執(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返回一個(gè)promise,參數(shù)也是一個(gè)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這個(gè)類。max表示同時(shí)可以執(zhí)行任務(wù)的最大數(shù)量。count用來記錄當(dāng)前正在執(zhí)行的異步函數(shù)。每次addTask都會(huì)通過scheduler.add添加一個(gè)異步任務(wù)。

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

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

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

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

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

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

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

相關(guān)文章

  • 常用DOM整理

    常用DOM整理

    js在操作DOM中存在著許多跨瀏覽器方面的坑,本文花了我將近一周的時(shí)間整理,我將根據(jù)實(shí)例整理那些大大小小的“坑”。
    2015-06-06
  • jQuery實(shí)現(xiàn)手風(fēng)琴特效

    jQuery實(shí)現(xiàn)手風(fēng)琴特效

    這篇文章主要為大家詳細(xì)介紹了前端js實(shí)現(xiàn)手風(fēng)琴效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • 詳解如何準(zhǔn)確判斷JavaScript中的數(shù)據(jù)類型

    詳解如何準(zhǔn)確判斷JavaScript中的數(shù)據(jù)類型

    JavaScript中,我們經(jīng)常需要判斷數(shù)據(jù)類型以便于正確地處理數(shù)據(jù),本文將介紹JavaScript中的數(shù)據(jù)類型判斷技術(shù),包括typeof操作符、instanceof操作符、Object.prototype.toString方法以及ES6新增的一些數(shù)據(jù)類型判斷方法,需要的朋友可以參考下
    2023-08-08
  • 使用js實(shí)現(xiàn)數(shù)據(jù)格式化

    使用js實(shí)現(xiàn)數(shù)據(jù)格式化

    這篇文章主要介紹了使用javascript實(shí)現(xiàn)數(shù)據(jù)格式化為字符串,非常的實(shí)用,這里推薦給有相同需求的小伙伴。
    2014-12-12
  • Echarts.js實(shí)現(xiàn)水滴球和海洋效果

    Echarts.js實(shí)現(xiàn)水滴球和海洋效果

    這篇文章介紹了Echarts.js實(shí)現(xiàn)水滴球和海洋效果的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 別了 JavaScript中的isXX系列

    別了 JavaScript中的isXX系列

    我們很容易被漂亮的代碼吸引,也不知不覺的在自己的代碼庫中加入這些。卻沒有冷靜的想過它們的優(yōu)劣。這不,我就收集了一系列形如 是否為……? 的判斷的boolean函數(shù)
    2012-08-08
  • Bootstrap每天必學(xué)之前端開發(fā)框架

    Bootstrap每天必學(xué)之前端開發(fā)框架

    Bootstrap每天必學(xué)之前端開發(fā)框架,今天這篇文章就帶著大家了解認(rèn)識(shí)當(dāng)下最流行的前端開發(fā)框架Bootstrap,bootstrap深受大家喜愛的原因到底是什么呢,我們一探究竟。
    2015-11-11
  • 原生JS生成九宮格

    原生JS生成九宮格

    這篇文章主要為大家詳細(xì)介紹了原生JS生成九宮格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • ES6學(xué)習(xí)教程之對(duì)象的擴(kuò)展詳解

    ES6學(xué)習(xí)教程之對(duì)象的擴(kuò)展詳解

    這篇文章主要給大家介紹了ES6中對(duì)象擴(kuò)展的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • 微信小程序自定義可滾動(dòng)的彈出框

    微信小程序自定義可滾動(dòng)的彈出框

    這篇文章主要為大家詳細(xì)介紹了微信小程序自定義可滾動(dòng)的彈出框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07

最新評(píng)論

甘泉县| 齐齐哈尔市| 盐津县| 女性| 普陀区| 拜城县| 祁连县| 镇安县| 无极县| 普陀区| 江安县| 基隆市| 邹城市| 牙克石市| 改则县| 虎林市| 茶陵县| 扎囊县| 梨树县| 鄂伦春自治旗| 鄂伦春自治旗| 忻城县| 陇西县| 安义县| 长宁区| 鹤庆县| 尖扎县| 北流市| 同仁县| 黄冈市| 汝城县| 永顺县| 射阳县| 久治县| 贞丰县| 波密县| 长子县| 万源市| 城步| 古浪县| 广元市|