javascript - Promise.all and building axios requests inside async function - Stack Overflow

I'm looping data to build multiple axios requests and in this async loop is an await for some data

I'm looping data to build multiple axios requests and in this async loop is an await for some data.

When I do this, Promise.all resolves before an error is thrown on one of the requests .catch(errror => {}) I purposely gave one bad data so the request would go to catch.

return new Promise((resolve) => {
    let requestArr = [];
    requestsData.forEach(async (data) => {
        let waitForThisData = await someFunction(data.id);
        requestArr.push(
            axios
             .post()
             .then((response) => {})
             .catch((error) => {})
        );
    });

    Promise.all(requestArr).then(() => {
        resolve(true);
    });
});

I'm testing this with 3 requests, 1 of which will go to catch. When I added breakpoints Promise.all already resolves before going to one of the requests catch.

If I remove the await code then I get my expected output, catch triggers first before the Promise.all resolves.

So why does Promise.all resolve before one of the request finishes(errors and goes to catch)?

I'm looping data to build multiple axios requests and in this async loop is an await for some data.

When I do this, Promise.all resolves before an error is thrown on one of the requests .catch(errror => {}) I purposely gave one bad data so the request would go to catch.

return new Promise((resolve) => {
    let requestArr = [];
    requestsData.forEach(async (data) => {
        let waitForThisData = await someFunction(data.id);
        requestArr.push(
            axios
             .post()
             .then((response) => {})
             .catch((error) => {})
        );
    });

    Promise.all(requestArr).then(() => {
        resolve(true);
    });
});

I'm testing this with 3 requests, 1 of which will go to catch. When I added breakpoints Promise.all already resolves before going to one of the requests catch.

If I remove the await code then I get my expected output, catch triggers first before the Promise.all resolves.

So why does Promise.all resolve before one of the request finishes(errors and goes to catch)?

Share Improve this question edited Dec 15, 2020 at 3:37 crimson589 asked Dec 15, 2020 at 3:25 crimson589crimson589 1,3282 gold badges21 silver badges40 bronze badges 7
  • So is your question "why does Promise.all resolve before the catch gets triggered inside the forEach loop"? What's your desired behavior? – codemonkey Commented Dec 15, 2020 at 3:33
  • @codemonkey Sorry, yes. made that more clear in my question. – crimson589 Commented Dec 15, 2020 at 3:37
  • Are you only interested to know why or are you actually trying to figure out a way to catch errors before the Promise.all resolves? I don't have much to offer as regards the former, but if it's the latter, I can suggest a few changes that will make your code behave in a way that makes sense. – codemonkey Commented Dec 15, 2020 at 3:45
  • It might help to post what output you are getting by including console statements in your functions above, not sure I fully understand the problem – cppNoob Commented Dec 15, 2020 at 3:49
  • @codemonkey the latter would be very helpful, thank you. – crimson589 Commented Dec 15, 2020 at 3:49
 |  Show 2 more ments

2 Answers 2

Reset to default 3

This will make your Promise.all resolve AFTER the catch inside the loop, or, indeed, after all the requests (successful or unsuccessful):

const axios = require('axios');

const someFunction = () => {
    return new Promise(resolve => {
        setTimeout(() => resolve('222'), 100)
    })
}

const requestsData = ['https://httpstat.us/200', 'https://httpstat.us/205', 'https://httpstat.us/306']
const requestArr = requestsData.map(async data => {
    let waitForThisData = await someFunction(data);
    return axios.post(data)
            .then(response => {})
            .catch(error => console.log(error.toString()))
});

Promise.all(requestArr).then(() => {
    console.log('resolved promise.all')
})

https://httpstat.us/306 will produce an erroneous call. You can try placing it anywhere within the requestsData array.

From what I can see, you are pushing promises to the requestArr asynchronously, so if you call promise.all on the array before it's filled. It's going to resolve when the promises in it resolve. By removing the await you are quickly pushing all the requests to the requestArr.

So to answer your question, it resolves because all of the requests in requestArr have resolved before the requestArr.push() has been called on your error promise.

You can try to use your own async foreach function to do this a better way.

async function asyncForEach(array, callback) {
  for (let index = 0; index < array.length; index++) {
    await callback(array[index], index, array);
  }
}

Now you can await the foreach before calling the Promise.all().

let requestArr = [];

await asyncForEach(requestsData, async (data) => {
    let waitForThisData = await someFunction(data.id);
    requestArr.push(
        axios
            .post()
            .then((response) => { })
            .catch((error) => { })
    );
});

Promise.all(requestArr).then(() => {
    resolve(true);
});

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

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信