日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对请求并发数做限制的通用RequestDecorator

發布時間:2024/9/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对请求并发数做限制的通用RequestDecorator 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用場景

在開發中,我們可能會遇到一些對異步請求數做并發量限制的場景,比如說微信小程序的request并發最多為5個,又或者我們需要做一些批量處理的工作,可是我們又不想同時對服務器發出太多請求(可能會對服務器造成比較大的壓力)。這個時候我們就可以對請求并發數進行限制,并且使用排隊機制讓請求有序的發送出去。

介紹

那么,接下來我們就來講一下如何實現一個通用的能對請求并發數進行限制的RequestDecorator。我們先來介紹一下它的功能:

  • 既然涉及到并發數限制,它就肯定允許用戶傳入最大并發數限制參數:maxLimit
  • 既然是一個通用的RequestDecorator,那么它應該允許使用者傳入其喜歡的異步api(比如ajax, fetch, axios等)。
  • 為了方便起見,也為了開發便利性,被RequestDecorator封裝后的request請求結果都返回一個promise。
  • 由于使用者傳入的異步api不一定是promise類型的,也可能是callback類型的,因此我們提供用戶一個needChange2Promise參數,使用者若傳入的是callback類型的api,它可以通過將這個參數設置為true來將callback類型轉化為promise類型。
  • 分析完功能后,接下來我們就來實現這個東西:

    實現

    具體代碼如下,每一步我基本都做了注釋,相信大家能看懂。

    const pify = require('pify');class RequestDecorator { constructor ({ maxLimit = 5, requestApi, needChange2Promise, }) { // 最大并發量 this.maxLimit = maxLimit; // 請求隊列,若當前請求并發量已經超過maxLimit,則將該請求加入到請求隊列中 this.requestQueue = []; // 當前并發量數目 this.currentConcurrent = 0; // 使用者定義的請求api,若用戶傳入needChange2Promise為true,則將用戶的callback類api使用pify這個庫將其轉化為promise類的。 this.requestApi = needChange2Promise ? pify(requestApi) : requestApi; } // 發起請求api async request(...args) { // 若當前請求數并發量超過最大并發量限制,則將其阻斷在這里。 // startBlocking會返回一個promise,并將該promise的resolve函數放在this.requestQueue隊列里。這樣的話,除非這個promise被resolve,否則不會繼續向下執行。 // 當之前發出的請求結果回來/請求失敗的時候,則將當前并發量-1,并且調用this.next函數執行隊列中的請求 // 當調用next函數的時候,會從this.requestQueue隊列里取出隊首的resolve函數并且執行。這樣,對應的請求則可以繼續向下執行。 if (this.currentConcurrent >= this.maxLimit) { await this.startBlocking(); } try { this.currentConcurrent++; const result = await this.requestApi(...args); return Promise.resolve(result); } catch (err) { return Promise.reject(err); } finally { console.log('當前并發數:', this.currentConcurrent); this.currentConcurrent--; this.next(); } } // 新建一個promise,并且將該reolsve函數放入到requestQueue隊列里。 // 當調用next函數的時候,會從隊列里取出一個resolve函數并執行。 startBlocking() { let _resolve; let promise2 = new Promise((resolve, reject) => _resolve = resolve); this.requestQueue.push(_resolve); return promise2; } // 從請求隊列里取出隊首的resolve并執行。 next() { if (this.requestQueue.length <= 0) return; const _resolve = this.requestQueue.shift(); _resolve(); } } module.exports = RequestDecorator;

    樣例代碼如下:

    const RequestDecorator = require('../src/index.js')// 一個callback類型的請求api async function delay(num, time, cb) { setTimeout(() => { cb(null, num); }, time); } // 通過maxLimit設置并發量限制,needChange2Promise將callback類型的請求api轉化為promise類型的。 const requestInstance = new RequestDecorator({ maxLimit: 5, requestApi: delay, needChange2Promise: true, }); let promises = []; for (let i = 0; i < 30; i++) { // 接下來你就可以像原來使用你的api那樣使用它,參數和原來的是一樣的 promises.push(requestInstance.request(i, Math.random() * 3000).then(result => console.log('result', result), error => console.log(error))); } async function test() { await Promise.all(promises); } test();

    這樣,一個能對請求并發數做限制的通用RequestDecorator就已經實現了。當然,這里還有很多可以繼續增加的功能點,比如

  • 允許使用者設置每個請求的retry次數。
  • 允許使用者對每個請求設置緩存處理。
  • 結語

    以上,就是本篇的全部內容。github倉庫地址點擊這里。歡迎大家點贊或者star下。如果大家有興趣的話,也可以一起來完善這個東西。這個項目還不成熟,可能還會有bug,歡迎大家在github上提issue幫助我完善它。如果覺得有幫助的話,麻煩點個贊哦,謝謝。

    轉:https://www.cnblogs.com/chenjg/p/9638613.html

    總結

    以上是生活随笔為你收集整理的对请求并发数做限制的通用RequestDecorator的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。