Make for loop asynchronous in JavaScript

Viewed 175

I have a function that consists of a for a loop. Loop runs for a certain time and after that returns a value. my only aim is to return the value, once the loop runs entirely. I tried with Promise and Async-Await but none of them work for me.

Async Function

async function getTotalQuestion(tag, question) {
    var output = [];
    for (let i = 0; i < question; i++) {
        getOne(tag).then((data) => {
                output.push(data);
            })
            .catch((err) => {
                console.log(err);

            })
    }
    return output;
}

calling of the async function

getTotalQuestion('eco', 9).then((data) => {
        question = data; //here data is coming as undefined
    })
    .catch((err) => {
        console.log(err)
    })
2 Answers

The problem in the above code is that it does not wait for getOne to push data into the output array. In order to get the correct output, you'll have to await the result of getOne inside the for loop.

async function getTotalQuestion(tag, question) {
    var output = [];
    for (let i = 0; i < question; i++) {
        try {
            var data = await getOne(tag);
            output.push(data);
        } catch (err) {
            console.log(err);
        }
    }
    return output;
}

If each getOne() call is independent of the other and can be called in any sequence, then you can use Promise.all() to asynchronously call multiple getOne() calls. Then await for all of them to complete before returning the total result from getTotalQuestion().

async function getTotalQuestion(tag, question) {
    try {
        return await Promise.all(Array(question).fill(0).map(_ => getOne(tag)));
    } catch (err) {
        console.log(err);
    }
}

If the order of calls to getOne() matter, then obviously the other answer posted works and you should await for each call in a for loop. Read more about Promise.all(). And learn more about the difference between Promise.all() and multiple await calls in this stack overflow post.

Related