DEV Community

Cover image for Don't make that function async.

Don't make that function async.

José Clovis Ramírez de la Rosa on July 19, 2018

Today's a good day to write Javascript code. ES2015 and the newest features that are coming to the language every year makes it a joy to use. With ...
Collapse
 
asti profile image
Asti

"Node process will have to start/stop and save/recover every function's execution state"

async/await is just syntactic sugar for Promises, which are essentially a callback abstraction. There's really no concept of starting/stopping.

Collapse
 
clovis1122 profile image
José Clovis Ramírez de la Rosa

Hey Asti,

I'm not sure about async/await being just syntactic sugar for Promises. Sure it was made to make it work with promises easier. If you've worked with Generators before, the concept of "awaiting" a function might look familiar to the concept of "yielding" a result. In both cases, you're giving the control back to the caller. When I say that the function start/stop and save/recover, I refer to this mechanism.

In fact, when you're targeting the browser when there's not much support for async/await syntax, you can use Babel to compile your async/await code to a generator which will yield until all the promises are resolved!. This article explains the concept in a very succinct way - medium.com/siliconwat/how-javascri...

Collapse
 
asti profile image
Asti

Both yielding and await rewrite the code behind the scenes to a state machine which handles control flow, to behave like co-routines. It's not special in any respect - it could well be user code. There's little overhead other than a few jump tables.

Collapse
 
nicolasini profile image
Nico S___

I see async/await being used as a way to write "cleaner" code a lot, to make it "flatter". But same deal with promises. We write them to wait for something that is async, but our code doesn't do anything else until is done. We might release the thread to deal with other calls (think of an API), but the current call is being dealt synchronously.
I'm yet to see an example where either promises, callbacks, or async/await are used to wait for some "side effect" but the current execution continues to do something useful while it waits...

Collapse
 
clovis1122 profile image
José Clovis Ramírez de la Rosa • Edited

Yo Nic,

Async/await looks beautiful when it's done in that way (to make async code look and feel as if it was sync). It makes it easier to deal with.

I think that starting long async functions as early as possible is a great idea. Sadly I don't have any straightforward example about starting a long process while still doing something useful with the current execution. When you do it, it's usually just firing and waiting for other async requests.

Occasionally on the Client, we fire a request to get/save some data, save the request promise in a variable, and perform some small checks before launching an UI update event. At the end we await the request to launch another UI update event with the outcome (success/failure).

Collapse
 
emkographics profile image
Emko

word up!

Collapse
 
uniibu profile image
uni

Just to note, Async/await does not block the whole Node interpreter, only the async function it self.

Collapse
 
hellokyyt profile image
Kyle Harrison

This is precisely what I was looking for, thank you

Collapse
 
hellokyyt profile image
Kyle Harrison

I know what you're saying, but when it comes time to do "real work", a grand majority of things rely on reading or persisting something before being able to continue on. It's an extremely rare circumstance where taking advantage of having a long running process do it's thing in a separate parallel whiel executing a bunch of other things that don't require it.

Yes, sending an email, you don't need to wait for a response for that. Cool. What else? It's one of the very few "fire and forget" things you can do like collecting analytical data.

One example I can think of, is generating a series of graphs for a page that shows off analytical data. You could spin off the collection of each graphs data into separate threads, and eventually come down to either a Promise.all to tie it all together, or just let each thread independently update the data on the shared main thread state.

But generally speaking? Things are pretty damn sequential. If it werent, we wouldn't have had "callback hell" at all in the first place. Longer running routines are usually doing data manipulation, and usually you can't do anything else until the data is ready to be read.

There's a reason "blocking languages" like PHP had been king for so damn long, it's really good at understanding how on the server side things work.

Client side is a very different beast where many different things can be happening all over the place in parallel. But the server of the web has only one real understanding: a tcp socket has been opened that sends a stateless Request to the server to be parsed, and a Response to send back out through the socket, and close it.

The only time this is different, is if we're taking advantage of manual WebSockets to deal with very different kinds of work, but even still, you're probably going to be waiting to take in the payload, parse the final payload, and basically just execute whatever subroutine you need like any HTTP request, wait for it to complete and then send it back out the socket.

The async / await stuff doesn't need to be on everything, agreed, but with it here, it sure makes this whole process 99% less painful to pick up a project again after months of not seeing it.

Collapse
 
jacksonelfers profile image
Jackson Elfers

I really prefer anonymous function callbacks. May not be pretty but they're obvious in how they interact with the functions around them. I try to use features that hypothetically older machines can handle even if I'm transpiling es6. If I lose my transpiler for some reason I can easily just make small adjustments to make it compliant for my clients "stone age" computers.

Collapse
 
acostalima profile image
André Costa Lima

If you are designing an API, functions involving IO operations are typically good candidates to be exposed asynchronously. In some cases, it may be worthwhile to expose both sync and async interfaces.

Collapse
 
guseyn profile image
Guseyn Ismayylov

The best way to write asynchronous code is use declarative programming, I would suggest Async Tree Pattern

Collapse
 
chackboom profile image
chackboom

You said "Every function would have to wait for every individual function to be resolved, then that function will get back the control" You are wrong.

Collapse
 
guseyn profile image
Guseyn Ismayylov

Why I Don't Use Promises and Async/Await Abstractions in Node: guseyn.com/posts/why-i-dont-use-pr...