Loop with async and await in JavaScript

Loop with async and await in JavaScript

boost the speed of async requests in order

Well, just got some problems in JavaScript loop with http request involved. Take a short note showing how to deal with them which got ideas from the post: JavaScript: async/await with forEach().

face the issue

Okay, let’s try the example with axios calls in a loop:

const axios = require('./node_modules/axios');

const getTitle = (num) => {
  return new Promise((resolve, reject) => {
    axios.get(`https://jsonplaceholder.typicode.com/posts/${num}`)
    .then(response => {
      return resolve(response.data.title)
    })
    .catch(error => {
      return reject(error.message)
    })
  })
}

[1, 2, 3, 4, 5].forEach(async (num) => {
  await getTitle(num).then((title) => {
    console.log(`num ${num}: ${title}`);
  })
})

console.log('Done')

Run this script with Node.js, you might see this:

Done
num 2: qui est esse
num 3: ea molestias quasi exercitationem repellat qui ipsa sit aut
num 1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
num 4: eum et est occaecati
num 5: nesciunt quas odio

The result is the same for a simple for loop:

for (let num of [1, 2, 3, 4, 5]) {
  getTitle(num).then((title) => {
    console.log(`num ${num}: ${title}`);
  })
}

Note the numbers were not in order.

In browsers with http request using fetch API, it’s the same result as Promises returned.

let’s update

async ForEach

In the mentioned post above, we can re-write our own “async ForEach” function:

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

Run it again with:

asyncForEach([1, 2, 3, 4, 5], async (num) => {
  await getTitle(num).then((title) => {
    console.log(`num ${num}: ${title}`);
  })
})

console.log('Done')

You will get:

Done
num 1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
num 2: qui est esse
num 3: ea molestias quasi exercitationem repellat qui ipsa sit aut
num 4: eum et est occaecati
num 5: nesciunt quas odio

Yeah, much better, but Done shows early. That’s because the asyncForEach is wrapped inside async that returns a Promise, however, we are not waiting for the Promise to be resolved. Okay, let’s move on to put all script inside the async.

const start = async() => {
  await asyncForEach([1, 2, 3, 4, 5], async (num) => {
    await getTitle(num).then((title) => {
      console.log(`num ${num}: ${title}`);
    })
  })
  console.log('Done')
}

start()

Well, you’ll get this result with the correct order:

num 1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
num 2: qui est esse
num 3: ea molestias quasi exercitationem repellat qui ipsa sit aut
num 4: eum et est occaecati
num 5: nesciunt quas odio
Done

async for

As the asyncForEach is actually using for loop, why not just use for loop that inside a async to do the same job:

const start = async() => {
  for (let num of [1, 2, 3, 4, 5]) {
    await getTitle(num).then((title) => {
      console.log(`num ${num}: ${title}`);
    })
  }
  console.log('Done')
}

start();

// ---
// num 1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
// num 2: qui est esse
// num 3: ea molestias quasi exercitationem repellat qui ipsa sit aut
// num 4: eum et est occaecati
// num 5: nesciunt quas odio
// Done

The result is sequentially logged one by one after each Promise resolved.

async map

Also, with Promise.all() you can get all results obtained and log them immediately:

const start = async () => {
  await Promise.all([1, 2, 3, 4, 5].map(async num => {
    await getTitle(num).then((title) => {
      console.log(`num ${num}: ${title}`);
    })
  }))
  console.log('Done')
}

start();

Much faster…

Thanks for all the examples online that make understanding easier… And, happy coding…

Ads by Google

林宏

Frank Lin

Hey, there! This is Frank Lin (@flinhong), one of the 1.41 billion 🇨🇳. This 'inDev. Journal' site holds the exploration of my quirky thoughts and random adventures through life. Hope you enjoy reading and perusing my posts.

YOU MAY ALSO LIKE

Practising closures in JavaScript

JavaScript Notes

2018.12.17

Practising closures in JavaScript

JavaScript is a very function-oriented language. As we know, functions are first class objects and can be easily assigned to variables, passed as arguments, returned from another function invocation, or stored into data structures. A function can access variable outside of it. But what happens when an outer variable changes? Does a function get the most recent value or the one that existed when the function was created? Also, what happens when a function invoked in another place - does it get access to the outer variables of the new place?

Using Liquid in Jekyll - Live with Demos

Web Notes

2016.08.20

Using Liquid in Jekyll - Live with Demos

Liquid is a simple template language that Jekyll uses to process pages for your site. With Liquid you can output complex contents without additional plugins.

Hands on IBM Cloud Functions with CLI

Tools

2020.10.20

Hands on IBM Cloud Functions with CLI

IBM Cloud CLI allows complete management of the Cloud Functions system. You can use the Cloud Functions CLI plugin-in to manage your code snippets in actions, create triggers, and rules to enable your actions to respond to events, and bundle actions into packages.

TOC