最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Queuing Promises (ES6) - Stack Overflow

programmeradmin5浏览0评论

I'm writing a NodeJS service that requests data from APIs. Under load, I don't want to hammer the API with potentially hundreds of simultaneous requests, so I am trying to queue up the requests so they are executed one-by-one and with a delay between them.

const request = require( 'request' );
class WebService {
  constructor() {
    this.RequestQueue = [];
  }

  _Get( uri, options, reply ) {
    return new Promise( ( resolve, reject ) => {
      request.get( uri, options, ( err, resp, body ) => {
        if ( err )
          reject( err );

        reply( resp );
        resolve( resp );
      } );
    } );
  }

  async onRequest( data, reply ) {
    this.RequestQueue.push( this._Get( data.uri, data.opts, reply ) );
  }

  async execute() {
    while( this.RequestQueue.length > 0 ) {
      var current = this.RequestQueue.shift();
      await current();
      await Utils.Sleep(5000); //promise that resolves after 5 seconds
    }
  }
}

Due to the nature of ES6 promises, they start executing when constructed, so this._Get() inside of the onRequest event returns a promise that is already executing. Is there a clean way to avoid this so that I can properly queue the request for later?

I'm writing a NodeJS service that requests data from APIs. Under load, I don't want to hammer the API with potentially hundreds of simultaneous requests, so I am trying to queue up the requests so they are executed one-by-one and with a delay between them.

const request = require( 'request' );
class WebService {
  constructor() {
    this.RequestQueue = [];
  }

  _Get( uri, options, reply ) {
    return new Promise( ( resolve, reject ) => {
      request.get( uri, options, ( err, resp, body ) => {
        if ( err )
          reject( err );

        reply( resp );
        resolve( resp );
      } );
    } );
  }

  async onRequest( data, reply ) {
    this.RequestQueue.push( this._Get( data.uri, data.opts, reply ) );
  }

  async execute() {
    while( this.RequestQueue.length > 0 ) {
      var current = this.RequestQueue.shift();
      await current();
      await Utils.Sleep(5000); //promise that resolves after 5 seconds
    }
  }
}

Due to the nature of ES6 promises, they start executing when constructed, so this._Get() inside of the onRequest event returns a promise that is already executing. Is there a clean way to avoid this so that I can properly queue the request for later?

Share Improve this question edited Jun 26, 2020 at 8:56 maxpaj 6,8417 gold badges41 silver badges63 bronze badges asked Jun 19, 2018 at 16:08 w0fw0f 9581 gold badge12 silver badges24 bronze badges 1
  • You can instead rate-limit right? – Shankar Shastri Commented Jun 19, 2018 at 16:12
Add a ment  | 

1 Answer 1

Reset to default 9

Try adding the request options to the queue instead of the actual request Promise:

onRequest(data, reply) {
    this.RequestQueue.push({ 
        uri: data.uri, 
        opts: data.opts, 
        reply: reply 
    });
}

async execute() {
    while(this.RequestQueue.length > 0) {
        var current = this.RequestQueue.shift();
        await this._Get(current.uri, current.opts, current.reply);
    }
}
发布评论

评论列表(0)

  1. 暂无评论