I'm struggling with .map loop and async function inside. I use request-promise for async requests.
import * as rp from 'request-promise';
const testArray = ['one', 'two', 'three'];
const link = 'https://somelink.com/';
const test = testArray.map(async (elem) => {
console.log('before', elem);
await rp.get(link)
.then(async () => {
console.log('success');
});
console.log('after', elem);
});
Promise.all(test);
The output of this code:
before one
before two
before three
success
after one
success
after three
success
after two
What I need is that the code to execute in the correct order with output like this:
before one
success
after one
before two
success
after two
before three
success
after three
Can't figure out what am I doing wrong. Please help.
.map()
is NOTasync
aware. It will not pause its loop for anawait
in the callback function you pass it. Instead, theawait
will just immediately cause theasync
function to return an unresolved promise and the.map()
will go right ahead with the other iterations of the loop. As you already seem to know the resulting array from.map()
will just be an array of those promises.If you want the loop to pause and wait for the
await
, so you can truly sequence your asynchronous operations, then use a plainfor
loop, not a.map()
loop.This will then execute your
rp.get()
operations in sequence waiting for the first one to complete before the second one is executed. Your.map()
loop was executing them all in parallel which means you do not control the order of execution.FYI, the
request()
library and the corresponding derivatives of it have been deprecated and will no longer be actively developed to add new features. There is a list of alternatives here that are recommended for all new projects. My favorite isgot()
which was built from the ground up to use promises, but you can pick whichever one has the features you want and/or an API you like.