javascript - How can I wait for multiple Promise.all() - Stack Overflow

I'm working with some old code and I'm trying to return results for two arrays of promises.S

I'm working with some old code and I'm trying to return results for two arrays of promises.

So basically body contains first and second which are arrays of ids. I know that the below code works for a small array of of 1 to 5 ids, but if I were to do a few hundred, would the resolve fire before I get the hundred of results from both promise arrays?

 const doSomething = (body) => {
    return new Promise((resolve, reject) => {
      const promisesOne = body.first.map((id) => 
        doSomethingOne(id)
      );

      const promisesTwo = body.second.map((id) => 
        doSomethingTwo(id)
      );

      let response = {
        first: {}
        second: {}
        headers: 'mock headers'
      };

      Promise.all(promisesOne).then((results) => {
        response.first = results;
      });

      Promise.all(promisesTwo).then((results) => {
        response.second = results;
      });

      resolve(response);
  });
};

Also I won't be able to refactor this to async/await as this codebase does not use it.

I'm working with some old code and I'm trying to return results for two arrays of promises.

So basically body contains first and second which are arrays of ids. I know that the below code works for a small array of of 1 to 5 ids, but if I were to do a few hundred, would the resolve fire before I get the hundred of results from both promise arrays?

 const doSomething = (body) => {
    return new Promise((resolve, reject) => {
      const promisesOne = body.first.map((id) => 
        doSomethingOne(id)
      );

      const promisesTwo = body.second.map((id) => 
        doSomethingTwo(id)
      );

      let response = {
        first: {}
        second: {}
        headers: 'mock headers'
      };

      Promise.all(promisesOne).then((results) => {
        response.first = results;
      });

      Promise.all(promisesTwo).then((results) => {
        response.second = results;
      });

      resolve(response);
  });
};

Also I won't be able to refactor this to async/await as this codebase does not use it.

Share Improve this question asked Sep 12, 2022 at 2:57 ffx292ffx292 7093 gold badges20 silver badges35 bronze badges 3
  • FYI your code always returns resolve() before you get results, no matter how large your arrays are – Phil Commented Sep 12, 2022 at 3:10
  • Avoid the Promise constructor antipattern! – Bergi Commented Sep 12, 2022 at 4:04
  • I would if I could... Unfortunately, it isn't my codebase. – ffx292 Commented Sep 13, 2022 at 1:28
Add a ment  | 

2 Answers 2

Reset to default 5

would the resolve fire before I get the ... results from both promise arrays?

Yes, absolutely because you aren't waiting for them to resolve.

Simply wrap the two Promise.all() promises in another Promise.all() to wait for everything then create the final object you want.

const doSomething = (body) => {
  return Promise.all([
    Promise.all(body.first.map(doSomethingOne)),
    Promise.all(body.second.map(doSomethingTwo)),
  ]).then(([first, second]) => ({
    first,
    second,
    headers: "mock headers",
  }));
};

You could make this generic by creating a map of body property names to their corresponding mapping function. For example

const mappers = {
  first: doSomethingOne,
  second: doSomethingTwo,
};

const doSomething = (body) => {
  return Promise.all(
    Object.entries(mappers).map(([key, mapper]) =>
      Promise.all(body[key].map(mapper)).then((data) => ({ [key]: data }))
    )
  )
  .then((results) => Object.assign({ headers: "mock headers" }, ...results));
};

Your code will not work at the moment - the resolve(response) will run before either of the Promise.alls are done.

First, refactor your .first and .second (etc) properties so that they're arrays, rather than unique string properties. Then, it'll be easy to .map them with two Promise.alls - one to wait for an individual array to fulfill, and an outer one to wait for all arrays to fulfill.

The same thing should be done for the doSomethingOne etc functions - to make the code easy to work with, use an array of functions instead of having many standalone identifiers.

Also, there's no need for the explicit Promise construction antipattern.

const doSomethings = [
  doSomethingOne, // define these functions here
  doSomethingTwo,
];

const doSomething = (body) => Promise.all(
  body.arrayOfArraysOfIds.map(
    (arr, i) => Promise.all(
      arr.map(id => doSomethings[i](id))
    )
  )
)
  .then((results) => ({
    headers: 'mock headers',
    results,
  });

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745156711a4614166.html

相关推荐

  • javascript - How can I wait for multiple Promise.all() - Stack Overflow

    I'm working with some old code and I'm trying to return results for two arrays of promises.S

    5小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信