Nika Kurashvili
Nika Kurashvili

Reputation: 6474

javascript map promises inside them

I am having this code:

signers.map(async (signer, tx) => {
   const address = await signer.getAddress();
   console.log(address);
   return { account: address, amount: 1 }
})

console.log("awesome");

The problem is that awesome gets printed first. How do I make sure that until all the promises are resolved inside map, it doesn't come to awesome. The cleanest way would be much appreciated.

Upvotes: 3

Views: 55

Answers (2)

geoffrey
geoffrey

Reputation: 2474

Note that there is nothing stopping you from awaiting Promise.all since it's just a promise of results;

const promises = signers.map(async (signer, tx) => {
   const address = await signer.getAddress();
   console.log(address);
   return { account: address, amount: 1 }
});

const results = await Promise.all(promises);

console.log("awesome");

Upvotes: 2

jfriend00
jfriend00

Reputation: 708056

All async functions return a promise that resolves when the body of the function has completed or rejects when an exception occurs.

And, .map() is not async-aware at all. It doesn't pause the loop waiting for the promise. So, you are running all your asynchronous operations in-flight at the same time and signers.map() returns an array of promises. If you want to know when they are all done and get the results of all those promises, you need to use Promise.all() on that array of promises.

let promises = signers.map(async (signer, tx) => {
   const address = await signer.getAddress();
   console.log(address);
   return { account: address, amount: 1 }
});

Promise.all(promises).then(results => {
    console.log("awesome");
    console.log(results);
}).catch(err => {
    console.log(err);
});

If, what you really want to do is to run your asynchronous operations serially, one after the other, then use a regular for loop in a containing async function because a for loop is async-aware and will pause the loop waiting for the await.

let addresses = [];
for (let signer of signers) {    
   const address = await signer.getAddress();
   console.log(address);
   addresses.push({ account: address, amount: 1 });
}
console.log(addresses);

Upvotes: 7

Related Questions