3

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
  • 1
    You must make the function inside the for loop to wait. Something like await getOne(tag)... Commented Feb 21, 2021 at 7:30
  • This sounds like an X/Y problem Commented Feb 21, 2021 at 7:33

2 Answers 2

4

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;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Yeah. The way I like to think about it is, imagine that getOne takes a long time, like 30 seconds to give you a result. In the original code, when i === 0 it'll start that 30 second process but not wait for it to finish and instead proceed to i === 1, etc. etc.
thanks, @kunal. it works. just one doubt, getOne is already a promise, promise itself an async method. it has to wait isn't it
@Pranaykumar Promise is a value that might resolve or reject in the future (with the stress on the future). Therefore, whenever a function returns a Promise, it might return a value (resolve) or throw an error (reject) but after it has completed processing. Now, in order to use the function's return value, one must explicitly wait (using await or then) for the it to finish it's task(s) and provide the required output.
0

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.

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.