4

I'm reading several articles and seeing some videos about how to use async/await in JavaScript and seems that the only reason is to transform asynchronous code in synchronous code (and make code more readable but this is not intended to be discussed in this question).

So, I would like to understand if there are more reasons on using these statements because, in my understanding, if we have Promises to make async calls and improve the performance of our code, why we want to convert it again to synchronous code?

jaloplo
  • 941
  • 2
  • 12
  • 32
  • 1
    I believe it's nothing but syntactic sugar. Promises are really hard to understand completely and many people never really get them fully right and good old nested callbacks don't scale nicely. – Álvaro González Jun 29 '19 at 10:23
  • 2
    It's not synchronous code. It's code that's running sequentially and asynchronously but still following control structures. Nothing more nothing less. – Bergi Jun 29 '19 at 10:27
  • 1
    Why do you think promises improve performance? They only make it simpler to deal with asynchronous results. – Bergi Jun 29 '19 at 10:28
  • @Bergi I'm also interested in how promises improve performance. Unless OP means "they don't hold up the thread" which could lead to the display freezing (in the browser)...but that just means "don't await if you have a very long task" – VLAZ Jun 29 '19 at 10:40
  • @Bergi Promises improve performance in the way you can run some different actions in the main thread running all of them asynchronous, so you are able to improve the time your function takes to execute. – jaloplo Jun 29 '19 at 10:51
  • @jaloplo No, promises don't do that. All promise and non-promise code runs on the main thread. Promises don't make anything asynchronous, they only provide a convenient wrapper around tasks that are already inherently asynchronous. – Bergi Jun 29 '19 at 11:57
  • @Bergi afaik, Promise.all method allows to run more than one task at a time. It will resolve when the longest task ends so you will not waste time running synchronously. Let me know if I'm wrong. I followed this video as the master for learning async/await https://youtu.be/vn3tm0quoqE – jaloplo Jun 29 '19 at 12:20
  • @jaloplo No, `Promise.all` doesn't run anything. It just creates a promise from an array of promises, promises that have already been created and (usually) started to run things. But it's those things that need to be asynchronous to run concurrently - `Promise.all` doesn't change anything about that. – Bergi Jun 29 '19 at 12:29
  • @Bergi totally agree with you, if methods are not async is not possible to run them async but, as I said, Promise.all makes able to save time running several async methods in the sense that you need their results independently. – jaloplo Jun 29 '19 at 12:58
  • @jaloplo It's possible to do the same without promises, so I'd say the speedup is not due to promises. Sure, `Promise.all` is *much* more convenient than writing the wait-for-all-results code by hand :-) – Bergi Jun 29 '19 at 13:00
  • @Bergi like to see a sample – jaloplo Jun 29 '19 at 13:02
  • 1
    @jaloplo `let count=0; function done() { console.log("callback", count); if (++count == 2) console.log("Both done"); } setTimeout(done, 1000); setTimeout(done, 1500);` - the two timeouts happen concurrently. Or use the async.js library or so for these things. – Bergi Jun 29 '19 at 13:10
  • @Bergi that's a trick. That's not the same as Promises, you execute ```done``` function after 1000 milliseconds and after 1500 milliseconds. You have to add the time the function consumes so it's more than you set for them. Definitely, that's not the same. – jaloplo Jun 29 '19 at 14:08
  • 1
    @jaloplo No, the two timeouts are occurring at the same time - try yourself. The times do not add, the "both done" logs when both of them have called the callback. It's not a trick, it's exactly the same mechanism that `Promise.all` uses internally to wait for multiple asynchronous promise resolutions. – Bergi Jun 29 '19 at 14:13
  • @Bergi, you are totally right. Thanks for letting me understand how it works. – jaloplo Jul 02 '19 at 06:18

3 Answers3

11

It can be considered to be not actually synchronous. When you await something that is async, it gets added to a microtask queue. It does not run on the main thread, meaning other things can occur (click events, rendering, etc.)

Here is a fantastic talk that can explain it in further detail https://www.youtube.com/watch?v=cCOL7MC4Pl0

await/async are often referred to as syntactic sugar, and let us wait for something (e.g. an API call), giving us the illusion that it is synchronous.

Toby Mellor
  • 8,093
  • 8
  • 34
  • 58
2

I think async await increases the readability of the code. In some promise-callback uses, you can find yourself in a very long chain, which can be called a callback pit. it is up to you to consider whether to use async-await.

Hayreddin Tüzel
  • 939
  • 2
  • 9
  • 22
-1

Sometimes you need multiple actions inside single functions, some of them may be asynchronous and some may be synchronous. Let's say you have following code with promises.

getUser().then(user => {
    getOrders({
        user: user
    }).then(orders => {
        console.log(orders)
    })
})

now what if you want orders to be fetched only if a condition is true, but let further code run as it is, then if you are using promises, you have to create a separate function and then call that function like this

function logOrders(orders) {
    console.log(orders)
}


getUser().then(user => {
    if (user.hasOrders) {
        getOrders({
            user: user
        }).then(logOrders)
    } else {
        logOrders([])
    }
})

but using async/await you can do it like this

(async () => {

    const user = await getUser();
    let orders = [];

    if (user.hasOrders) {
        orders = await getOrders({
            user: user
        })
    }

    console.log(orders)

})()
Shridhar Sharma
  • 2,337
  • 1
  • 9
  • 13
  • No, [you don't need a separate function](https://stackoverflow.com/a/26600424/1048572). – Bergi Jun 29 '19 at 10:29
  • How will you do that? – Shridhar Sharma Jun 29 '19 at 10:33
  • you have to wait conditionally for getOrders() to complete – Shridhar Sharma Jun 29 '19 at 10:33
  • Did you check the link? Also, `getUser().then(user => user.hasOrders ? getOrders({user}) : []).then(orders => console.log(orders));` – Bergi Jun 29 '19 at 10:33
  • how will you access the user variable inside the last then method? – Shridhar Sharma Jun 29 '19 at 10:37
  • See [How do I access previous promise results in a `.then()` chain?](https://stackoverflow.com/q/28250680/1048572) For example, `getUser().then(user => (user.hasOrders ? getOrders({user}) : Promise.resolve([])).then(orders => console.log(user, orders)));` (Notice that your separate function doesn't achieve this at all) – Bergi Jun 29 '19 at 10:38
  • that's what async and await do – Shridhar Sharma Jun 29 '19 at 10:39
  • Yes, `async`/`await` makes it simpler, it's one of the great uses that improves readability (see my accepted answer to the other question). But no, a separate function is not necessary for conditional promises, and still it's only a readability advantage which the OP was not asking about. – Bergi Jun 29 '19 at 10:41
  • I explained how the same thing can be done with better readability via both Promises and async/await – Shridhar Sharma Jun 29 '19 at 10:43
  • and obviously creating separate function is more readable than the method you shared – Shridhar Sharma Jun 29 '19 at 10:44
  • But the fact remains that your statement--"...you have to create a separate function..."--is incorrect. – Daniel Dec 03 '20 at 17:54