不到50行代码实现一个能对请求并发数做限制的通用RequestDecorator
生活随笔
收集整理的這篇文章主要介紹了
不到50行代码实现一个能对请求并发数做限制的通用RequestDecorator
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用場景
在開發中,我們可能會遇到一些對異步請求數做并發量限制的場景,比如說微信小程序的request并發最多為5個,又或者我們需要做一些批量處理的工作,可是我們又不想同時對服務器發出太多請求(可能會對服務器造成比較大的壓力)。這個時候我們就可以對請求并發數進行限制,并且使用排隊機制讓請求有序的發送出去。
介紹
那么,接下來我們就來講一下如何實現一個通用的能對請求并發數進行限制的RequestDecorator。我們先來介紹一下它的功能:
分析完功能后,接下來我們就來實現這個東西:
實現
具體代碼如下,每一步我基本都做了注釋,相信大家能看懂。
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;}// 發起請求apiasync 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 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就已經實現了。當然,這里還有很多可以繼續增加的功能點,比如
優點:
結語
以上,就是本篇的全部內容。github倉庫地址點擊這里。歡迎大家點贊或者star下。如果大家有興趣的話,也可以一起來完善這個東西。這個項目還不成熟,可能還會有bug,歡迎大家在github上提issue幫助我完善它。如果覺得有幫助的話,麻煩點個贊哦,謝謝。 本文地址在->本人博客地址, 歡迎給個 start 或 follow
總結
以上是生活随笔為你收集整理的不到50行代码实现一个能对请求并发数做限制的通用RequestDecorator的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当面试官问你如何进行性能优化时,你该这么
- 下一篇: 你真的了解css像素嘛?