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?
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With