How do you re-organize this async-await code

How do you re-organize this async-await code
0

I just wanna make 3 async requests. When the first is done, send the 2 others at the same time.

const req_users = () => {
  return fetch(api_base + 'users')
}

const req_posts = () => {
  return fetch(api_base + 'unknown')
}

const create_user = () => {
  return fetch(api_base + 'users?delay=2', { method: 'POST' })
}

async function start () {
  try {
    const create_user_resp = await create_user()
    const create_user_json = create_user_resp.json()
    const users_req = req_users()
    const posts_req = req_posts()
    const users_resp = await users_req
    const posts_resp = await posts_req
    const users_json = users_resp.json()
    const posts_json = posts_resp.json()
    console.log('user: ', (await create_user_json))
    console.log('users: ', (await users_json))
    console.log('posts: ', (await posts_json))
  } catch (error) {
    console.log(error)
  }
}

start()

As you can see, the start function looks very silly, I am not sure how to make it looks better while keeps the logic correct.

Thanks

You don’t really need the intermediate variables users_req and posts_req. You can just await them like you do with create_user_resp.

You don’t need to (and can’t) await the values in the console.log statements, because they’re plain values, not promises.

I’d also add the console.log statements immediately after where the variable it’s logging is set, so in case one of your statements bombs, you’ll still get some logs.

Also for logging errors, I prefer console.error which will highlight the error in red on browser dev consoles.

You actually don’t need to catch and log errors at all in this though – logging the error is the default behavior for uncaught errors. Your catch block is actually logging and ignoring the error, which is not good practice.

Finally, your create_user is posting nothing. Mixing a query string with post is also not good practice, though it’s not quite as clear-cut when it’s giving options to the backend unrelated to the data. Still, it’s more standard practice to put metadata in the post entity.

If I understand, you want to wait for create_user() to complete and then run req_users() and req_posts() at the same time? If so, then you can’t use await in front of them because that will cause the execution to stop until they return (so whichever one you call first, the second one won’t be called until the first one finishes).

You have a few options. You could just call them as normal and process the information returned with then(). Or you could use await Promise.all([...]) which will run them both at the same time and wait for them to finish.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Oh look, I even found a write-up on freeCodeCamp for Promise.All()

Thanks, I read something about promise.all and async/await usages. Here is my new function.

async function start () {
  try {
    const create_user_resp = await create_user()
    const create_user_json = await create_user_resp.json()
    console.log(create_user_json)

    const resp = await Promise.all([req_users(), req_posts()])
    return await Promise.all(resp.map(res => res.json()))
  } catch (error) {
    console.log(error)
  }
}

Thanks guys.

resp doesn’t contain promises – that’s the point of Promise.all. So you can just return resp.map(res => res.json())

Hi, sorry, but you forgot res.json() return promise :smiley:,