0

I am wondering what is the best practice when we need to call an asynchronous function on each elements of an array and wait for all the Promises to resolve. Assume that we do not need to change the original array.

For instance, let's say that I have an array of objects that each need to be built asynchronously with a build() function, which return a Promise. I need to wait for them to be built before moving on with following instructions. Currently, I will do the following.

async function myFunction() {
    await Promise.all(myObjArray.map(myObj => myObj.build()));
    {...}
}

However, I think that this may be a bad way to do it because the Array.prototype.map() function should not be used in that case, as per the documentation. However, I do not know what would be a good alternative since forEach would not work.

When not to use map()

Since map builds a new array, using it when you aren't using the returned array is an anti-pattern; use forEach or for...of instead.

You shouldn't be using map if:

you're not using the array it returns; and/or you're not returning a value from the callback.

Thanks!

4
  • 2
    map() is exactly what is required as Promise.all() takes an array and your map call returns an array of unresolved promises. Commented Jun 8, 2021 at 23:20
  • Oh so the array IS used by Promise.all! I had not figured that and thought that it was just discarded... I will accept that as answer if you want to post it. Commented Jun 8, 2021 at 23:21
  • Do you want to run all the .build() operations in parallel or in sequence? Your proposed use of .map() runs them all in parallel. Commented Jun 8, 2021 at 23:38
  • @jfriend00 I want to run them in parallel. Commented Jun 9, 2021 at 0:19

1 Answer 1

1

this may be a bad way to do it because the Array.prototype.map() function should not be used in that case, as per the documentation:

Since map builds a new array, using it when you aren't using the returned array is an anti-pattern; use forEach or for...of instead.

It's not a bad way. You are using the returned array: you're passing it to Promise.all. It doesn't work without that. obj.build() returns a promise, and you need to collect those into an array. map is the perfect solution for that.

It would be even better if the promises don't fulfill with undefined (i.e. have no result), but with the built object, so that you would write

async function buildFrom(oldObj) {
    …
    return newObj;
}
const builtObjects = await Promise.all(myObjArray.map(buildFrom));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.