1

How to call async function over an array of elements synchronously in such a way that the next async function should be called only after the completion of async call over the current element.

for instance if we look at the following piece of code.

const fetch = require("cross-fetch");

function wait(a) {
    fetch(`https://jsonplaceholder.typicode.com/todos/${a}`)
        .then(response => response.json())
        .then(json => console.log(json));
}
const data = [1, 2, 3, 5, 6, 7, 8, 9, 10];

async function test() {
    for (const ele of data) {
        await wait(ele);
    }
}

test();

whenever I am executing the above piece of code it is logging responses randomly but not synchronously according to the array. i.e

{"userId":1,"id":8,"title":"quo adipisci enim quam ut ab","completed":true}
{"userId":1,"id":9,"title":"molestiae perspiciatis ipsa","completed":false}
{"userId":1,"id":10,"title":"illo est ratione doloremque quia maiores aut","completed":true}
{"userId":1,"id":7,"title":"illo expedita consequatur quia in","completed":false}
{"userId":1,"id":1,"title":"delectus aut autem","completed":false}
{"userId":1,"id":6,"title":"qui ullam ratione quibusdam voluptatem quia omnis","completed":false}
{"userId":1,"id":3,"title":"fugiat veniam minus","completed":false}
{"userId":1,"id":5,"title":"laboriosam mollitia et enim quasi adipisci quia provident illum","completed":false}
{"userId":1,"id":2,"title":"quis ut nam facilis et officia qui","completed":false}

Here you can clearly see that the responses are not in order. Is there any way that these function can be called synchronously but only after completing the current call.

3
  • for await .. of Commented Jun 5, 2020 at 18:16
  • still confused with it? can you tell how it works @HereticMonkey Commented Jun 5, 2020 at 18:21
  • Just go with the answer you've got from spender. Commented Jun 5, 2020 at 18:24

4 Answers 4

3

You function wait is not returning its Promise, so you're actually awating undefined (I'm surprised this doesn't blow-up). Therefore asynchrony is happening in a fire-and-forget fashion. All promises are started in the same execution frame (rather than in consecutive order when the previous promise completes).

Add a return statement here:

function wait(a) {
  return fetch(`https://jsonplaceholder.typicode.com/todos/${a}`)
    .then(response => response.json())
    .then(json => console.log(json));
}

By returning the Promise, the await in your loop will now block (asynchronously) until the returned Promise completes. The rest of your code now operates as expected.

Sign up to request clarification or add additional context in comments.

Comments

1
function wait(a) {
    return fetch(`https://jsonplaceholder.typicode.com/todos/${a}`)
        .then(response => response.json());
}
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

async function test() {
    for await (const ele of data) {
        await wait(ele).then(json => console.log(JSON.stringify(json)));
    }
}

Hopefully, This will work .

Comments

0

From MDN, await expression...

causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment. When resumed, the value of the await expression is that of the fulfilled Promise.

However, in your function, the function is returning null undefined, and also from the docs,

If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise.

async function test() {
    for (const ele of data) {
        // returned value from wait(el) is not a promise, it's null
        await wait(ele);
    }
}

Adding a return should fix it!

function wait(a) {
    // missing return statement 
    // to fix, add a `return` infront of fetch
    fetch(`https://jsonplaceholder.typicode.com/todos/${a}`)
        .then(response => response.json())
        .then(json => console.log(json));
}

1 Comment

null and undefined are different things in JS. A void function "returns" undefined, not null.
-1

Just wrap the function's code inside of a Promise, like this:

function wait(a) {
  return new Promise((resolve, reject) => {
    fetch(`https://jsonplaceholder.typicode.com/todos/${a}`)
      .then(response => resolve(response.json()))
      .then(json => reject(json));
    });  
}

Then the rest of the code should work as expected.

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.