DEV Community

7 Reasons Why JavaScript Async/Await Is Better Than Plain Promises (Tutorial)

Mostafa Gaafar on July 29, 2019

Async/await was introduced in NodeJS 7.6 and is currently supported in all modern browsers. I believe it has been the single greatest addition to J...
Collapse
 
welingtonms profile image
Welington Silva

Important to mention that, although it looks cleaner, easier to read and everything, mainly for new developers, using async/await may trick you into not seeing points of opportunity for parallelism and you end up with a series of asynchronous call being treated as a plain synchronous code. For that cases where's there's in no need wait for things to be ran sequentially, Promise.all to the rescue!

Collapse
 
gafi profile image
Mostafa Gaafar

I don't really agree with this. You can make the same mistake with promises or async/await. You can still chain the promises instead of calling them in parallel

Collapse
 
welingtonms profile image
Welington Silva • Edited

You surely can. My point here is not to confuse new devs making them think one replaces the other, because it doesn't. They are two tools you can combine to make the best out of your async flows.
Good post, by the way!

Thread Thread
 
kenbellows profile image
Ken Bellows

tbh I tend to get a little weird with parallel promises and combine destructuring, await, and Promise.all():

const [val1, val2, val3] = await Promise.all(promise1(), promise2(), promise3())
Enter fullscreen mode Exit fullscreen mode

kinda gross, but personally I prefer it to returning to promise chains

Thread Thread
 
welingtonms profile image
Welington Silva • Edited

Yeah, I do that myself (I don't think that's gross at all). That's the combination I think makes sense: we get the benefits of async/await without giving up the parallelism.

Collapse
 
ffxsam profile image
Sam Hulick • Edited

Debugging async/await is actually a total pain if you're working in a project that's using babel. If you're stepping through your code, the minute you hit an async call, you're thrown into polyfill. If you're aware of a workaround, I'd love to know about it!

Collapse
 
ironydelerium profile image
ironydelerium

Disable that in Babel and let it spit out the actual async/await code instead of polyfilling it. (I do that for various other features as well, HTML custom elements being a big one, since there isn't a good way to write those in an ES3 compatible manner; new.target and Reflect didn't become available until after classes, and since you need to call 'super()' or equivalent in the constructor...)

Combined with webpack or the like, I'm not sure there, I have yet to use it.

Collapse
 
ffxsam profile image
Sam Hulick

Not all browsers that I need to support can use async/await, unfortunately, so I need to let babel handle that still.

Thread Thread
 
ironydelerium profile image
ironydelerium

I get that entirely, but for the initial testing and debugging of such code, I'd still turn it off. It lets you get your logic in order without having to debug a polyfill at the same time.

Thread Thread
 
ffxsam profile image
Sam Hulick

Ah, I gotcha - just for the purpose of debugging. Makes sense!

Collapse
 
termita81 profile image
RP

Hi, this is probably a silly question, but how do you disable those generators in Babel? Thanks

Collapse
 
gafi profile image
Mostafa Gaafar

That's interesting I don't think I had this problem. Do you have source maps enabled?

Collapse
 
ffxsam profile image
Sam Hulick

For context, this is in a Vue project (created with vue-cli 3), and it's in a local dev environment so source maps shouldn't matter I don't think? I'll have to do another test with this and see if it's still an issue.

Collapse
 
davidmaxwaterman profile image
Max Waterman

You can’t set breakpoints in arrow functions that return expressions (no body).

Works fine in chrome dev tools.

I like a lot about await, but I don't like having to use try/catch - it's not a construct I'm used to...it forces me to use 'let' instead of 'const' if I want to have access outside the catch block. Also, it indents one more level. Perhaps I need to learn try/catch more, but I note your examples tend not to show error handling, except the one where it is claimed as an advantage.

Collapse
 
gafi profile image
Mostafa Gaafar

I share your dislike of try/catch, but it's the only way to handle errors in synchronous code, so we don't really have a choice. Async/await enables us to use just 1 approach to handle both sync & async errors. I'd prefer to handle all errors in the same way, even if it's not my favorite way πŸ€·β€β™€οΈ

Collapse
 
davidmaxwaterman profile image
Max Waterman

I also don't really like the aspect that it hides what is going on. It looks synchronous, but definitely isn't.
Then there's the kangaroo behaviour when stepping through it, which isn't expected from its "sequential" appearance.
Imo, it's trying to be "too clever".
... having said that, I still find myself using it.

Collapse
 
carddamom profile image
Carlos Santos Roque

Async/Await are promises! What your examples do not show is that your async/await functions actually do not return just string, but instead they return Promise, you can get away by returning just a string, because the compiler or interpreter wrapps them in a Promise, actually the whole async/await function gets converted to an promise based one.

Collapse
 
aonkar profile image
Anandteerth Onkar

I have been working on JS/TS past 2 years. Understanding Asynchronous JS, had become a challenge. This article has really given a good clarity on Async/Await.

Kudos! to you man.

I got your reference by Kait Hoehne, she has written an excellent article titled - Is JavaScript Synchronous or Asynchronous?:
betterprogramming.pub/is-javascrip...

I will be referencing your article, if I plan to write a blog on JS synchrounous & Asynchronous.

Collapse
 
gafi profile image
Mostafa Gaafar • Edited

I wouldn't call it better because this code does 2 things that I try to avoid generally:

  1. Mutation
  2. One-line if conditions

I try to make code easier to read and trace, even if it becomes a little more verbose

Collapse
 
wizardrogue profile image
Joseph Angelo Barrozo

Good read. Didn't know about #7, thanks man!

Collapse
 
acostalima profile image
AndrΓ© Costa Lima

I'm not entirely sure if this is still the case, but there are also performance reasons at stake related to stacktrace reconstruction to justify preference of async/await vs promises in V8.
Source: mathiasbynens.be/notes/async-stack...

Collapse
 
oriash93 profile image
Ori Ashual

Great read, thanks!
Just a small note - you're missing the word "Reasons" in the title :)

Collapse
 
gafi profile image
Mostafa Gaafar

Oops. Fixed it. Thanks

Collapse
 
ben profile image
Ben Halpern

Great post πŸ˜„

Collapse
 
realityexpander profile image
Chris Athanas

Nice work

Collapse
 
calistus profile image
Ilo Calistus

Great Article @gafi .
I currently use Await/async on Dart; and I understand it better now.
Promises can really be a pain especially when they are nested.

Collapse
 
wrldwzrd89 profile image
Eric Ahnell

YAY! JS needs this. Writing code this way is a lot easier... mind you, it's not perfect, but it's better than what we had before.