Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to handle nested async await calls in Node? [duplicate]

Tags:

Trying to learn the async pattern in Javascript but it doesn't appear that it waits for the following line. In the following example, the collection is the request object and not the actual parsed body. Isn't await supposed to wait for the request to finish?

async function importUsers(endpoint) {     const options = {         data: search,         uri: endpointCollection,         headers,     }      try {         const collection = await browser.post(options, (err, res, body) => JSON.parse(body))         // collection is the request object instead of the result of the request         const users = await collection.data.forEach(item => parseUserProfile(item));          await users.forEach(user => saveUserInfo(user))     } catch(err) {         handleError(err)     } }    async function parseUserProfile({ username, userid }) {     const url = userProfileString(username)      try {         const profile = await browser.get(url, headers, (err, res, body) => {                return { ... } // data from the body         })     } catch(err) {         handleError(err)     } } 
like image 933
user3162553 Avatar asked May 20 '17 19:05

user3162553


People also ask

How do I handle multiple async-await in node JS?

In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).

Can I nest async functions?

async functions returning promises is a good thing because you can nest async functions.

Can I use async-await in node?

Async functions are available natively in Node and are denoted by the async keyword in their declaration. They always return a promise, even if you don't explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment – it cannot be used in the global scope.


2 Answers

Async/Await only works on functions that return (and resolve) a promise.

The following example will write to the console after 3 seconds, and then continue on.

// Tell the browser that this function is asynchronous  async function myFunc() {      // Await for the promise to resolve      await new Promise((resolve) => {          setTimeout(() => {              // Resolve the promise              resolve(console.log('hello'));          }, 3000);      });      // Once the promise gets resolved continue on      console.log('hi');  }    // Call the function  myFunc();

Without async/await, the output would be as follows:

hi hello 

Here is an example without async/await:

// Tell the browser that this function is asynchronous  async function myFunc() {      // Skip await      new Promise((resolve) => {          setTimeout(() => {              // Resolve the promise              resolve(console.log('hello'));          }, 3000);      });      // Since await was not used, this will print first      console.log('hi');  }    // Call the function  myFunc();

This would be because the hi output would run and then after 3 seconds the timeout would run.

But with async/await, the output looks like this:

hello hi 

This is because we await for the timeout then we run the hi output.

like image 53
Get Off My Lawn Avatar answered Sep 20 '22 16:09

Get Off My Lawn


await should expect a promise, for a callback style async function, you can transform it like:

new Promise((resolve, reject) => browser.post(options, (err, res, body) => resolve(JSON.parse(body)))) 

For an array, you need to map it to an array of promises, then use Promise.all to turn it to a 'promise of array', for example:

Promise.all(collection.data.map(item => parseUserProfile(item))) 
like image 41
rstar Avatar answered Sep 19 '22 16:09

rstar