Reputation: 2540
I have a main function that makes a series of GET requests in parallel. Their status is evaluated using the Promise.all
function.
var promises = [];
for ( var i = 0; i < list.length; i++ )
{
promises.push( REQ( list[ i ], 0 ) );
}
var responses = await Promise.all( promises );
The REQ
function returns a promise.
async function REQ( url, attempts )
{
await sleep( 5000 * attempts ); // Uses a promise with setTimeout
return new Promise( ( resolve, reject ) => {
request( url, function ( error, response, body )
{
if ( error )
{
if ( attempts > ATTEMPT_THRESHOLD )
reject( error );
else
return REQ( url, ++attempts );
}
else
{
if ( typeof body === 'undefined' || body.length === 0 )
{
if ( attempts > ATTEMPT_THRESHOLD )
reject( error );
else
return REQ( url, ++attempts );
}
else
resolve( { response, body } );
}
});
});
};
The reason I've made the REQ
function async
is so that if a request fails, it gets re-attempted, but the re-attempt is delayed a little in case the server it's querying is congested.
The issue seems to be that in the Node console, the program hangs on a re-attempt, such that if a REQ
fails, the re-attempt of it doesn't return to the original REQ
and return the promise.
Upvotes: 1
Views: 122
Reputation: 664493
The re-attempt of it doesn't return to the original REQ and return the promise.
Of course not. In a new Promise
constructor, you need to resolve
the promise not return
it.
It would be much better if you promisified on the lowest possible level, i.e. just wrap request
and only request
, not any of the retry business logic:
function requestAsync(url) {
return new Promise((resolve, reject) => {
request(url, (error, response, body) => {
if (error) reject(error);
else resolve({response, body});
});
});
}
Then you can use await
and return
as usual.
async function REQ(url, attempts) {
try {
const res = await requestAsync(url);
if (typeof res.body == "undefined" || res.body.length == 0)
throw new Error("no response"); // or throw undefined to get the original behaviour
return res;
} catch(error) {
if (attempts > ATTEMPT_THRESHOLD)
throw error;
++attempts;
await sleep(5000 * attempts);
return REQ(url, attempts);
}
}
Upvotes: 2