AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

前端開發中大并發量如何控制并發數

來源: 責編: 時間:2024-05-07 09:15:44 172觀看
導讀寫在前面最近在進行移動端h5開發,首頁需要加載的資源很多,一個lottie動效需要請求70多張圖片,但是遇到安卓webview限制請求并發數,導致部分圖片請求失敗破圖。當然圖片資源可以做閑時加載和預加載,可以減輕播放動效時資源

i8P28資訊網——每日最新資訊28at.com

寫在前面

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

i8P28資訊網——每日最新資訊28at.com

上面代碼基本實現了前端并發請求的需求,也基本滿足需求,在生產中其實有很多已經封裝好的庫可以直接使用。比如:p-limit【https://github.com/sindresorhus/p-limit】i8P28資訊網——每日最新資訊28at.com

閱讀p-limit源碼

import Queue from 'yocto-queue';import {AsyncResource} from '#async_hooks';export default function pLimit(concurrency) { // 判斷這個參數是否是一個大于0的整數,如果不是就拋出一個錯誤 if (  !((Number.isInteger(concurrency)  || concurrency === Number.POSITIVE_INFINITY)  && concurrency > 0) ) {  throw new TypeError('Expected `concurrency` to be a number from 1 and up'); } // 創建隊列 -- 用于存取請求 const queue = new Queue(); // 計數 let activeCount = 0; // 用來處理并發數的函數 const next = () => {  activeCount--;  if (queue.size > 0) {   // queue.dequeue()可以理解為[].shift(),取出隊列中的第一個任務,由于確定里面是一個函數,所以直接執行就可以了;   queue.dequeue()();  } }; // run函數就是用來執行異步并發任務 const run = async (function_, resolve, arguments_) => {  // activeCount加1,表示當前并發數加1  activeCount++;  // 執行傳入的異步函數,將結果賦值給result,注意:現在的result是一個處在pending狀態的Promise  const result = (async () => function_(...arguments_))();  // resolve函數就是enqueue函數中返回的Promise的resolve函數  resolve(result);  // 等待result的狀態發生改變,這里使用了try...catch,因為result可能會出現異常,所以需要捕獲異常;  try {   await result;  } catch {}  next(); }; // 將run函數添加到請求隊列中 const enqueue = (function_, resolve, arguments_) => {  queue.enqueue(   // 將run函數綁定到AsyncResource上,不需要立即執行,對此添加了一個bind方法   AsyncResource.bind(run.bind(undefined, function_, resolve, arguments_)),  );  // 立即執行一個異步函數,等待下一個微任務(注意:因為activeCount是異步更新的,所以需要等待下一個微任務執行才能獲取新的值)  (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,并且隊列中有任務,如果滿足條件就會將隊列中的任務取出來執行   if (activeCount < concurrency && queue.size > 0) {    // 注意:queue.dequeue()()執行的是run函數    queue.dequeue()();   }  })(); }; // 接收一個函數fn和參數args,然后返回一個Promise,執行出隊操作 const generator = (function_, ...arguments_) => new Promise(resolve => {  enqueue(function_, resolve, arguments_); }); // 向外暴露當前的并發數和隊列中的任務數,并且手動清空隊列 Object.defineProperties(generator, {  // 當前并發數  activeCount: {   get: () => activeCount,  },  // 隊列中的任務數  pendingCount: {   get: () => queue.size,  },  // 清空隊列  clearQueue: {   value() {    queue.clear();   },  }, }); return generator;}

整個庫只有短短71行代碼,在代碼中導入了yocto-queue庫,它是一個微型的隊列數據結構。i8P28資訊網——每日最新資訊28at.com

手寫源碼

在進行手撕源碼時,可以借助數組進行簡易的實現:i8P28資訊網——每日最新資訊28at.com

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()();        }    }}

小結

在這篇文章中,簡要介紹了為什么要進行并發請求,闡述了使用請求池隊列實現并發請求的設計思路,簡要實現代碼。i8P28資訊網——每日最新資訊28at.com

此外,還閱讀分析了p-limit的源碼,并使用數組進行簡要的源碼編寫,以實現要求。i8P28資訊網——每日最新資訊28at.com

參考文章

  • 【源碼共讀】大并發量如何控制并發數https://juejin.cn/post/7179220832575717435?searchId=20240430092814392DC2208C545E691A26
  • 前端實現并發控制網絡請求https://mp.weixin.qq.com/s/9uq2SqkcMSSWjks0x7RQJg。

本文鏈接:http://www.tebozhan.com/showinfo-26-87046-0.html前端開發中大并發量如何控制并發數

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 如何優雅的變更Docker Desktop的鏡像存儲路徑

下一篇: 盤點Lombok的幾個操作,你記住了嗎?

標簽:
  • 熱門焦點
  • 中興AX5400Pro+上手體驗:再升級 雙2.5G網口+USB 3.0這次全都有

    2021年11月的時候,中興先后發布了兩款路由器產品,中興AX5400和中興AX5400 Pro,從產品命名上就不難看出這是隸屬于同一系列的,但在外觀設計上這兩款產品可以說是完全沒一點關系
  • 28個SpringBoot項目中常用注解,日常開發、求職面試不再懵圈

    前言在使用SpringBoot開發中或者在求職面試中都會使用到很多注解或者問到注解相關的知識。本文主要對一些常用的注解進行了總結,同時也會舉出具體例子,供大家學習和參考。注解
  • K6:面向開發人員的現代負載測試工具

    K6 是一個開源負載測試工具,可以輕松編寫、運行和分析性能測試。它建立在 Go 和 JavaScript 之上,它被設計為功能強大、可擴展且易于使用。k6 可用于測試各種應用程序,包括 Web
  • 線程通訊的三種方法!通俗易懂

    線程通信是指多個線程之間通過某種機制進行協調和交互,例如,線程等待和通知機制就是線程通訊的主要手段之一。 在 Java 中,線程等待和通知的實現手段有以下幾種方式:Object 類下
  • 使用LLM插件從命令行訪問Llama 2

    最近的一個大新聞是Meta AI推出了新的開源授權的大型語言模型Llama 2。這是一項非常重要的進展:Llama 2可免費用于研究和商業用途。(幾小時前,swyy發現它已從LLaMA 2更名為Lla
  • 破圈是B站頭上的緊箍咒

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之每年的暑期檔都少不了瞄準追劇女孩們的古偶劇集,2021年有優酷的《山河令》,2022年有愛奇藝的《蒼蘭訣》,今年卻輪到小破站抓住了追
  • 2天漲粉255萬,又一賽道在抖音爆火

    來源:運營研究社作者 | 張知白編輯 | 楊佩汶設計 | 晏談夢潔這個暑期,旅游賽道徹底火了:有的「地方」火了&mdash;&mdash;貴州村超旅游收入 1 個月超過 12 億;有的「博主」火了&m
  • 10天營收超1億美元,《星鐵》比《原神》差在哪?

    來源:伯虎財經作者:陳平安即便你沒玩過《原神》,你一定聽說過的它的大名。恨它的人把《原神》開服那天稱作是中國游戲史上最黑暗的一天,有粉絲因為索尼在PS平臺上線《原神》,怒而
  • 榮耀Magicbook V 14 2021曙光藍版本正式開售,擁有觸摸屏

    榮耀 Magicbook V 14 2021 曙光藍版本正式開售,搭載 i7-11390H 處理器與 MX450 顯卡,配備 16GB 內存與 512GB SSD,重 1.48kg,厚 14.5mm,具有 1.5mm 鍵盤鍵程、
Top