精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

前端開發(fā)中大并發(fā)量如何控制并發(fā)數(shù)

開發(fā) 前端
在這篇文章中,簡要介紹了為什么要進行并發(fā)請求,闡述了使用請求池隊列實現(xiàn)并發(fā)請求的設計思路,簡要實現(xiàn)代碼。此外,還閱讀分析了p-limit的源碼,并使用數(shù)組進行簡要的源碼編寫,以實現(xiàn)要求。

寫在前面

最近在進行移動端h5開發(fā),首頁需要加載的資源很多,一個lottie動效需要請求70多張圖片,但是遇到安卓webview限制請求并發(fā)數(shù),導致部分圖片請求失敗破圖。當然圖片資源可以做閑時加載和預加載,可以減輕播放動效時資源未加載的問題。

同樣的,業(yè)務開發(fā)也會遇到需要異步請求幾十個接口,如果同時并發(fā)請求瀏覽器會進行限制請求數(shù),也會給后端造成請求壓力。

場景說明

現(xiàn)在有個場景:

請你實現(xiàn)一個并發(fā)請求函數(shù)concurrencyRequest(urls, maxNum),要求如下:

  • 要求最大并發(fā)數(shù) maxNum。
  • 每當有一個請求返回,就留下一個空位,可以增加新的請求。
  • 所有請求完成后,結果按照 urls 里面的順序依次打出(發(fā)送請求的函數(shù)可以直接使用fetch即可)。

初始實現(xiàn):

const preloadManger = (urls, maxCount = 5) => {
  let count = 0; // 計數(shù) -- 用于控制并發(fā)數(shù)
  const createTask = () => {
    if (count < maxCount) {
      const url = urls.pop(); // 從請求數(shù)組中取值
      if (url) {
        // 無論請求是否成功,都要執(zhí)行taskFinish
        loader(url).finally(taskFinish);
        // 添加下一個請求
        count++;
        createTask();
      }
    }
  };

  const taskFinish = () => {
    count--;
    createTask();
  };

  createTask();
};

// 進行異步請求
const loader = async (url) => {
  const res = await fetch(url).then(res=>res.json());
  console.log("res",res);
  return res
}

const urls = [];
for (let i = 1; i <= 20; i++) {
    urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
}

preloadManger(urls, 5)

請求狀態(tài):

可以看到上面的請求是每五個一組進行請求,當一個請求無論返回成功或是失敗,都會從請求數(shù)組中再取一個請求進行補充。

設計思路

那么,我們可以考慮使用隊列去請求大量接口。

思路如下:

假定最大并發(fā)數(shù)是maxNum=5,圖中對接口進行了定義編號,當請求隊列池中有一個請求返回后,就向池子中新增一個接口進行請求,依次直到最后一個請求執(zhí)行完畢。

當然,要保證程序的健壯性,需要考慮一些邊界情況,如下:

  • 當初始請求數(shù)組urls的長度為0時,此時請求結果數(shù)組results是個空數(shù)組。
  • 最大并發(fā)數(shù)maxNums>urls的長度時,請求數(shù)為urls的長度。
  • 需要定義計數(shù)器count去判斷是否全部請求完畢。
  • 無論請求成功與否,都應該將結果存在結果數(shù)組results中。
  • 結果數(shù)組results和urls數(shù)組的順序保持一致,方便存取。

代碼實現(xiàn)

在前面的初始實現(xiàn)的代碼中,雖然都能滿足基本需求,但是并沒有考慮一些邊界條件,對此需要根據(jù)上面設計思路重新實現(xiàn)得到:

// 并發(fā)請求函數(shù)
const concurrencyRequest = (urls, maxNum) => {
    return new Promise((resolve) => {
        if (urls.length === 0) {
            resolve([]);
            return;
        }
        const results = [];
        let index = 0; // 下一個請求的下標
        let count = 0; // 當前請求完成的數(shù)量

        // 發(fā)送請求
        async function request() {
            if (index === urls.length) return;
            const i = index; // 保存序號,使result和urls相對應
            const url = urls[index];
            index++;
            console.log(url);
            try {
                const resp = await fetch(url);
                // resp 加入到results
                results[i] = resp;
            } catch (err) {
                // err 加入到results
                results[i] = err;
            } finally {
                count++;
                // 判斷是否所有的請求都已完成
                if (count === urls.length) {
                    console.log('完成了');
                    resolve(results);
                }
                request();
            }
        }

        // maxNum和urls.length取最小進行調(diào)用
        const times = Math.min(maxNum, urls.length);
        for(let i = 0; i < times; i++) {
            request();
        }
    })
}

測試代碼:

const urls = [];
for (let i = 1; i <= 20; i++) {
    urls.push(`https://jsonplaceholder.typicode.com/todos/${i}`);
}
concurrencyRequest(urls, 5).then(res => {
    console.log(res);
})

請求結果:

上面代碼基本實現(xiàn)了前端并發(fā)請求的需求,也基本滿足需求,在生產(chǎn)中其實有很多已經(jīng)封裝好的庫可以直接使用。比如:p-limit【https://github.com/sindresorhus/p-limit】

閱讀p-limit源碼

import Queue from 'yocto-queue';
import {AsyncResource} from '#async_hooks';

export default function pLimit(concurrency) {
 // 判斷這個參數(shù)是否是一個大于0的整數(shù),如果不是就拋出一個錯誤
 if (
  !((Number.isInteger(concurrency)
  || concurrency === Number.POSITIVE_INFINITY)
  && concurrency > 0)
 ) {
  throw new TypeError('Expected `concurrency` to be a number from 1 and up');
 }

 // 創(chuàng)建隊列 -- 用于存取請求
 const queue = new Queue();
 // 計數(shù)
 let activeCount = 0;

 // 用來處理并發(fā)數(shù)的函數(shù)
 const next = () => {
  activeCount--;

  if (queue.size > 0) {
   // queue.dequeue()可以理解為[].shift(),取出隊列中的第一個任務,由于確定里面是一個函數(shù),所以直接執(zhí)行就可以了;
   queue.dequeue()();
  }
 };

 // run函數(shù)就是用來執(zhí)行異步并發(fā)任務
 const run = async (function_, resolve, arguments_) => {
  // activeCount加1,表示當前并發(fā)數(shù)加1
  activeCount++;

  // 執(zhí)行傳入的異步函數(shù),將結果賦值給result,注意:現(xiàn)在的result是一個處在pending狀態(tài)的Promise
  const result = (async () => function_(...arguments_))();

  // resolve函數(shù)就是enqueue函數(shù)中返回的Promise的resolve函數(shù)
  resolve(result);

  // 等待result的狀態(tài)發(fā)生改變,這里使用了try...catch,因為result可能會出現(xiàn)異常,所以需要捕獲異常;
  try {
   await result;
  } catch {}

  next();
 };

 // 將run函數(shù)添加到請求隊列中
 const enqueue = (function_, resolve, arguments_) => {
  queue.enqueue(
   // 將run函數(shù)綁定到AsyncResource上,不需要立即執(zhí)行,對此添加了一個bind方法
   AsyncResource.bind(run.bind(undefined, function_, resolve, arguments_)),
  );

  // 立即執(zhí)行一個異步函數(shù),等待下一個微任務(注意:因為activeCount是異步更新的,所以需要等待下一個微任務執(zhí)行才能獲取新的值)
  (async () => {
   // This function needs to wait until the next microtask before comparing
   // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously
   // when the run function is dequeued and called. The comparison in the if-statement
   // needs to happen asynchronously as well to get an up-to-date value for `activeCount`.
   await Promise.resolve();

   // 判斷activeCount是否小于concurrency,并且隊列中有任務,如果滿足條件就會將隊列中的任務取出來執(zhí)行
   if (activeCount < concurrency && queue.size > 0) {
    // 注意:queue.dequeue()()執(zhí)行的是run函數(shù)
    queue.dequeue()();
   }
  })();
 };

 // 接收一個函數(shù)fn和參數(shù)args,然后返回一個Promise,執(zhí)行出隊操作
 const generator = (function_, ...arguments_) => new Promise(resolve => {
  enqueue(function_, resolve, arguments_);
 });

 // 向外暴露當前的并發(fā)數(shù)和隊列中的任務數(shù),并且手動清空隊列
 Object.defineProperties(generator, {
  // 當前并發(fā)數(shù)
  activeCount: {
   get: () => activeCount,
  },
  // 隊列中的任務數(shù)
  pendingCount: {
   get: () => queue.size,
  },
  // 清空隊列
  clearQueue: {
   value() {
    queue.clear();
   },
  },
 });

 return generator;
}

整個庫只有短短71行代碼,在代碼中導入了yocto-queue庫,它是一個微型的隊列數(shù)據(jù)結構。

手寫源碼

在進行手撕源碼時,可以借助數(shù)組進行簡易的實現(xiàn):

class PLimit {
    constructor(concurrency) {
        this.concurrency = concurrency;
        this.activeCount = 0;
        this.queue = [];
        
        return (fn, ...args) => {
            return new Promise(resolve => {
               this.enqueue(fn, resolve, args);
            });
        }
    }
    
    enqueue(fn, resolve, args) {
        this.queue.push(this.run.bind(this, fn, resolve, args));

        (async () => {
            await Promise.resolve();
            if (this.activeCount < this.concurrency && this.queue.length > 0) {
                this.queue.shift()();
            }
        })();
    }
    
    async run(fn, resolve, args) {
        this.activeCount++;

        const result = (async () => fn(...args))();

        resolve(result);

        try {
            await result;
        } catch {
        }

        this.next();
    }
    
    next() {
        this.activeCount--;

        if (this.queue.length > 0) {
            this.queue.shift()();
        }
    }
}

小結

在這篇文章中,簡要介紹了為什么要進行并發(fā)請求,闡述了使用請求池隊列實現(xiàn)并發(fā)請求的設計思路,簡要實現(xiàn)代碼。

此外,還閱讀分析了p-limit的源碼,并使用數(shù)組進行簡要的源碼編寫,以實現(xiàn)要求。

參考文章

  • 【源碼共讀】大并發(fā)量如何控制并發(fā)數(shù)https://juejin.cn/post/7179220832575717435?searchId=20240430092814392DC2208C545E691A26
  • 前端實現(xiàn)并發(fā)控制網(wǎng)絡請求https://mp.weixin.qq.com/s/9uq2SqkcMSSWjks0x7RQJg。
責任編輯:姜華 來源: 宇宙一碼平川
相關推薦

2017-08-21 10:56:55

MySQL并發(fā)控制

2021-01-12 10:22:45

JavaScript并發(fā)控制前端

2021-04-07 06:00:18

JavaScript 前端并發(fā)控制

2024-06-17 08:40:16

2022-12-12 09:07:06

Redis并發(fā)限流

2009-09-24 14:43:53

Hibernate樂觀

2009-06-09 09:32:48

LinuxApache帶寬控制

2023-11-20 08:01:38

并發(fā)處理數(shù)Tomcat

2010-11-08 10:57:05

SQL Server的

2021-06-29 23:40:19

Golang語言并發(fā)

2021-02-25 22:17:19

開發(fā)技術編程

2009-11-25 11:41:56

IIS最大并發(fā)數(shù)

2020-01-13 10:20:30

架構聊天架構百萬并發(fā)量

2009-02-09 10:06:03

并發(fā)控制Web應用悲觀鎖

2017-02-28 17:46:15

Linux驅動技術并發(fā)控制

2025-02-26 03:00:00

2025-02-28 00:03:22

高并發(fā)TPS系統(tǒng)

2017-11-06 17:16:55

Linux設備驅動并發(fā)控制

2023-01-30 15:41:10

Channel控制并發(fā)

2024-08-26 13:23:26

點贊
收藏

51CTO技術棧公眾號

欧美日韩国产中文精品字幕自在自线| 国产99久久久久久免费看农村| 国产亚洲一区精品| 亚洲欧美一区二区三区不卡| 丁香花在线高清完整版视频 | 天天综合日日夜夜精品| 日本精品一区二区| 国产福利第一页| 久久一区亚洲| 欧美国产精品日韩| 亚洲综合欧美综合| 精品视频在线你懂得| 欧美日韩国产天堂| 99热在线这里只有精品| www视频在线免费观看| 久久影院午夜论| 粉嫩av四季av绯色av第一区| www.av88| 午夜亚洲一区| 久久久久久网站| 亚洲综合网在线| 凹凸成人精品亚洲精品密奴| 亚洲国产精彩中文乱码av在线播放| www.这里只有精品| 在线精品亚洲欧美日韩国产| 亚洲精品国产无天堂网2021| 日本高清一区| 日本一区高清| eeuss影院一区二区三区| 91社区国产高清| 中文字幕一区二区人妻| 久久午夜影视| 人人澡人人澡人人看欧美| 久久久综合久久| 亚洲精品一区二区在线看| 国产亚洲精品久久久久久777| 日本一区二区免费视频| 天堂av一区| 91精品在线观看入口| 麻豆三级在线观看| 欧美日韩精品一区二区三区视频| 黄色成人在线播放| 成人在线国产视频| 成人免费一区二区三区牛牛| 亚洲人成影院在线观看| 亚洲欧洲久久| 色多多视频在线观看| 国产精品理论在线观看| 日韩免费毛片| 777电影在线观看| 国产精品视频观看| 亚洲一区二区三区精品视频| 77导航福利在线| 国产精品久久久久久久久免费桃花 | 欧美插天视频在线播放| 亚洲最大的黄色网址| 亚洲国产精品日韩专区av有中文| 色av中文字幕一区| 国产一区第一页| 欧美一区二区三区久久精品| 欧美理论片在线观看| 久久久国产精华液| 亚洲免费成人| 日本国产高清不卡| 中文无码av一区二区三区| 麻豆精品视频在线观看| 91视频免费在线| 国模无码一区二区三区| 久久综合久久综合久久综合| 久久久久高清| 福利在线午夜| 亚洲视频网在线直播| 日韩亚洲欧美一区二区| 2001个疯子在线观看| 欧美日韩亚洲成人| 热久久精品免费视频| 欧美综合影院| 精品999在线播放| 亚洲第一成人网站| 99国产精品免费视频观看| 欧美猛交免费看| youjizz在线视频| 久久99精品国产| 国产一区二区三区四区五区在线| 国自产拍在线网站网址视频| 亚洲日韩欧美一区二区在线| 欧美午夜小视频| 成人mm视频在线观看| 日韩欧美亚洲一区二区| 无码人妻精品一区二区三应用大全| 成人在线国产| 欧美精品aaa| 国产主播第一页| 国产精品资源在线看| 欧美日韩一区二区视频在线| 麻豆视频网站在线观看| 亚洲成精国产精品女| 999精品视频在线| 国产精品久久久久av蜜臀| 亚洲成人av在线| 精品少妇一区二区三区密爱| 一区二区日本视频| 亚洲精品欧美日韩专区| 二人午夜免费观看在线视频| 亚洲国产精品一区二区尤物区| www.99av.com| 亚洲自拍都市欧美小说| 欧美不卡视频一区发布| 国产精品尤物视频| 97久久精品人人爽人人爽蜜臀| 一区二区三区精品国产| 欧美艳星kaydenkross| 欧美哺乳videos| 亚洲少妇xxx| 老牛影视一区二区三区| 国产一区二区不卡视频| 超碰电影在线播放| 欧美丝袜丝交足nylons| 高潮毛片无遮挡| 亚洲电影在线| 91在线观看网站| 欧洲不卡av| 在线看国产一区二区| 国产精品第七页| 激情久久五月| 国产精品精品软件视频| 伊人影院在线视频| 欧美精品久久一区| 刘亦菲国产毛片bd| 日本中文字幕一区二区有限公司| 麻豆av一区二区三区久久| 多野结衣av一区| 精品国产一区二区三区久久久蜜月| 成人在线观看小视频| 精品一区二区在线视频| 亚洲亚洲精品三区日韩精品在线视频| 少妇一区视频| 亚洲美女中文字幕| 五月婷婷色丁香| 久久综合九色综合97_久久久| 每日在线观看av| 开心激情综合| 69影院欧美专区视频| 免费观看成年人视频| 亚洲五月六月丁香激情| 欧美肉大捧一进一出免费视频| 亚洲视频精品| 国产在线一区二| 麻豆mv在线看| 亚洲精品自拍偷拍| 天码人妻一区二区三区在线看| 97久久超碰国产精品| 色欲av无码一区二区人妻| 啄木系列成人av电影| 国产精品第10页| av在线电影观看| 欧美日韩和欧美的一区二区| 一本一本久久a久久| 国产在线精品视频| 丁香六月激情网| 欧美大胆视频| 国产精品久久久久久超碰| av黄色在线观看| 91精品国产品国语在线不卡| 久久久久久激情| 91在线你懂得| 亚洲欧美在线精品| 欧美黄在线观看| 麻豆久久久9性大片| 台湾成人免费视频| 久久久av免费| 日本xxxxwww| 一本色道**综合亚洲精品蜜桃冫| 国产一区二区三区精品在线| 国内精品视频一区二区三区八戒| 日韩a级黄色片| 亚洲深夜福利在线观看| 91精品久久久久久久| 黄色污污视频在线观看| 亚洲欧美日韩中文视频| 国产精品欧美激情在线| 午夜私人影院久久久久| 久久视频精品在线观看| 国产东北露脸精品视频| 男人操女人免费软件| 国产精品久久观看| 欧美91福利在线观看| 亚洲人成色777777精品音频| 国产蜜臀97一区二区三区| 国产自偷自偷免费一区| 一区二区美女| 国产精品视频色| 中文字幕在线播放网址| 日韩高清不卡av| 亚洲视屏在线观看| 亚洲精品成a人| 人人妻人人澡人人爽人人精品| 日韩电影免费在线看| av 日韩 人妻 黑人 综合 无码| 天天躁日日躁狠狠躁欧美| 国产在线精品一区免费香蕉 | 国产精品一区二区三区精品 | 一本久久精品一区二区| 亚洲精品久久久久久国| 粉嫩av亚洲一区二区图片| 一级黄色香蕉视频| 亚洲成人中文| 尤物国产精品| 偷拍自拍一区| 97自拍视频| 男人亚洲天堂| 国产成人精品免费视频| av有码在线观看| 久久综合久久八八| 国产剧情在线观看| 亚洲精品电影网在线观看| av网站在线免费看| 欧美探花视频资源| 丰满少妇xoxoxo视频| 亚洲国产欧美在线人成| 国产成人av免费在线观看| 国产日产欧美一区二区视频| 丰满岳乱妇一区二区| 狠狠色丁香婷综合久久| 在线观看的毛片| 久久国产88| 黄页免费在线观看视频| 欧美精品三区| 蜜臀av.com| 91精品蜜臀一区二区三区在线| 欧美成人一区二区在线| 精品深夜福利视频| 国产伦精品一区二区三毛| 欧美日韩黄网站| 成人免费视频网| 日韩精品第二页| 国产精品视频永久免费播放| 欧美调教sm| 97视频com| caoporn视频在线| 国产综合在线视频| 538在线精品| 91精品国产色综合久久不卡98口 | 国产成人精品av在线| 超级碰碰久久| 国产成人91久久精品| 韩日成人影院| 国产精品久久久久久久久久免费| 不卡一二三区| 国产精品视频免费观看www| 深夜视频一区二区| 国产一区二区丝袜| 国产精品777777在线播放| 97久草视频| 久久aimee| 麻豆一区区三区四区产品精品蜜桃| 欧美aaaaa级| 欧美激情专区| 色偷偷综合网| 国产香蕉一区二区三区| 欧美日本一区| 男人天堂1024| 蜜桃精品视频在线| 夜夜爽久久精品91| av网站一区二区三区| 亚洲国产精品成人综合久久久| 久久久.com| 看免费黄色录像| 亚洲6080在线| 五月天中文字幕| 欧美一区二区三区在线观看 | 福利视频一二区| 亚洲综合不卡| www.com污| 成人国产精品免费观看视频| 99久久久久久久久久| 国产精品青草久久| 欧美人妻一区二区| 日韩欧美在线视频日韩欧美在线视频| 这里只有久久精品视频| 欧美一区二区三区日韩| 天天摸夜夜添狠狠添婷婷| 曰本色欧美视频在线| 一区二区三区伦理| 日本精品一区二区三区在线| 精品久久国产一区| 欧美一级爱爱| 韩国精品一区二区三区| 青青青国产在线视频| 国产成人鲁色资源国产91色综| 不卡一区二区在线观看| 亚洲天堂免费在线观看视频| 午夜影院在线看| 91精品婷婷国产综合久久竹菊| 欧美熟妇乱码在线一区| 色爱av美腿丝袜综合粉嫩av| 国精产品一区一区三区mba下载| 国产精品91久久久| 北条麻妃在线一区二区免费播放| 日韩欧美视频一区二区| 精品1区2区3区4区| 亚洲va在线va天堂va偷拍| av午夜一区麻豆| 麻豆chinese极品少妇| 欧美主播一区二区三区| 婷婷av一区二区三区| 欧美成人精品h版在线观看| 希岛爱理一区二区三区av高清| **亚洲第一综合导航网站| 欧美限制电影| 亚洲午夜精品久久久久久人妖| 韩国视频一区二区| 亚洲精品成人av久久| 色综合天天综合网天天狠天天| 国产高清视频免费| 精品国产一区二区三区久久久狼 | 亚洲aa中文字幕| 色喇叭免费久久综合网| 日本三级免费观看| 波多野结衣在线aⅴ中文字幕不卡| 日韩高清dvd碟片| 欧美三级视频在线| 国产永久免费高清在线观看| 97碰在线观看| 老司机成人在线| 黄色大片中文字幕| 国产大片一区二区| 九九热精品免费视频| 欧美一区二区在线视频| 蜜桃视频在线观看免费视频网站www| 日本高清不卡的在线| 亚洲国产最新| 精品国产成人av在线免| 99精品视频在线播放观看| 精品少妇theporn| 欧美成人福利视频| 俄罗斯一级**毛片在线播放| av日韩免费电影| 国内久久视频| 黑人玩弄人妻一区二区三区| 尤物视频一区二区| 亚洲成熟女性毛茸茸| 久久99精品国产99久久6尤物| 国产中文欧美日韩在线| 日本大胆人体视频| 国产999精品久久久久久| 国产在线观看免费视频今夜| 精品免费一区二区三区| 春色校园综合激情亚洲| 玖玖玖精品中文字幕| 久久久精品日韩| 殴美一级黄色片| 日韩一区二区在线看| 国内在线视频| 鲁片一区二区三区| 蜜桃av一区二区在线观看 | 欧美日韩美女在线| 天天躁日日躁狠狠躁喷水| 4438全国亚洲精品在线观看视频| 天海翼精品一区二区三区| 欧美一级片中文字幕| 欧美国产一区二区| 国产精品九九九九| 欧美黑人极品猛少妇色xxxxx| 极品尤物一区| 五月天婷婷激情视频| 中文字幕日本乱码精品影院| 国产人妖在线播放| 性欧美亚洲xxxx乳在线观看| 久久爱www成人| 亚洲精品综合在线观看| 亚洲国产日产av| 超碰在线国产| 99re视频在线播放| 国产一区二区三区久久| 四虎成人免费影院| 欧美成人艳星乳罩| 成人欧美magnet| 色爽爽爽爽爽爽爽爽| www.欧美日韩国产在线| 波多野结衣网站| 欧美黄色www| 欧美美女一区| 国产香蕉精品视频| 在线视频你懂得一区| 五月婷婷视频在线观看| 欧美日韩精品中文字幕一区二区| 久久超碰97中文字幕| 亚洲视频免费播放| 日韩中文字幕在线| 人体久久天天| 久久精品一二三四| 色婷婷综合久久| 日本aa在线| 一区二区免费电影| 久久综合中文字幕| 亚洲伦理在线观看| 国产一区欧美二区三区| 欧美专区18| 久久久无码一区二区三区|