Live data from Hacker News

I Avoid Async/Await

uniqname.medium.com

71–80 of 242 posts

Re: I Avoid Async/Await

#71

First off, async/await is promises. It's merely syntactic sugar. The point of async/await is not to never have the word "Promise" appear in your code. It's also not meant to be universally better than using Promises bare-bones. A lot of the argument appears to be the author extrapolating from his own lack of familiarity to others: "We are taught", "our minds", etc. I can easily construe some hypothetical person with…

Async/await is certainly not promises. In fact it would be much better implemented without promises as I proposed here: https://es.discourse.group/t/callback-based-simplified-async...

I would even say that async/await is anti-promise, it takes the main functionality of promises, a caching layer for results and errors that allows you to add the code continuation later and elsewhere (which is a major footgun imo) and coerces the execution flow back to going on the next line and provided immediately at compile time which results in a cleaner flow but not as clean, stateless, efficient or functional as if you were to remove the promises completely. Having an additional caching layer and state machine around every asynchronous function call is quite inefficient.

The essence of async/await is not promises, it's the underlying javascript generator (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...) functionality combined with asynchronous code to stop and start the generator. It's the ability to pause and resume function execution based on asynchronous operations.

The promise functionality, the caching layer and state machine for results is basically sanitized away with async/await, it becomes dead-weight computation. The only benefit of promises in async/await code is being able to more easily interface with other promise laden code which you don't need once you have async/await and a library like https://www.npmjs.com/package/async for more complex cases.

Note that promises based async/await is also a mess of an implementation that breaks stack traces and needs to support tons of odd statement corner cases (basically anything that can return an object that could be a promise) whereas a continuation passing style async/await would be a much simpler implementation that would only apply to function calls and maintain stack traces. We would get that stack trace support automatically because of the great work of whoever implemented javascript generators which seem to already carry stack traces across paused/resumed functions (if you don't wrap in promises).

Re: I Avoid Async/Await

#72

Earlier quoted context omitted.

This, very much this. async function() {} is much nicer than function() { return new Promise( (resolve) => resolve() ) }

I prefer async/await but this is a contrived example. For starters you can just write: const myfunc = () => new Promise(resolve => resolve()) or Promise.resolve()

As soon as you need to chain Promises, this gets very annoying and you quickly find yourself in a nested callback hell.

Re: I Avoid Async/Await

#73

Earlier quoted context omitted.

new Promise() is not how you want to create a promise in JS (except when you really have to), just like 'new'/'delete' are not how you ant to allocate memory in C++ (except when you really have to). There are lots of helpers in that class that make promises significantly more ergonomic.

Care to give some examples of the helpers? I always just use new Promise()

You really end up creating promises manually, the vast majority are downstream from an IO call like fetch() or a database query.

Re: I Avoid Async/Await

#74
post #68

Earlier quoted context omitted.

I didn’t read the article like that at all. How would you handle two asynchronous saves which can happen in parallel without using a Promise.all? Don’t think you can…and that’s pretty much the entire point of the article. Async/await is useless unless you are willing to serialize your calls defeating the entire point of async code.

const x = somethingAsync(); const y = somethingAsyncToo(); return { foo: await x, bar: await y } There is no point in returning one before the other because you need both?

But in JavaScript, these two awaits will not happen in parallel, you really need to await Promise.all() for that.

Re: I Avoid Async/Await

#75
In that first example, `await` means exactly the same thing as `then` for the purposes the author is talking about -- realizing that something had been serialized that could have been done in parallel.

I don't see why most engineers would be likely to recognize that opportunity when written as `then` but not as `await`. If is is true (and I'm not convinced it is), it seems like an education problem rather than a reason to use promises rather than await. It doesn't seem fundamentally harder to know that two `awaits` in a row means serialization than to know that two `thens` in a row does.

At least in that simple example where the use of `then` is exactly parallel to the use of `await`. Perhaps it wasn't a good example, and it really would be harder to reason about in a more complicated example.

Re: I Avoid Async/Await

#76
post #74

Earlier quoted context omitted.

const x = somethingAsync(); const y = somethingAsyncToo(); return { foo: await x, bar: await y } There is no point in returning one before the other because you need both?

But in JavaScript, these two awaits will not happen in parallel, you really need to await Promise.all() for that.

You've really missed the point spectacularly of that example.

Both those promises start, and both are waited for after both have started..

That is the same as promise.all... There's just an explicit order for the wait, rather than as they resolve, but the result is the same.

Now, promise.any.... You'd have a point...

Re: I Avoid Async/Await

#77
post #62

Earlier quoted context omitted.

async/await is not the same as the do-notation, that's why.

How is it not?

Many reasons, for example:

1. do notation works and is used for any monadic type (e.g. lists, parsers, promises, resources like database-connection-contexts, ...) while async/await works for promises only

2. async works on the function-level and only there while do-notation can be used in any place where a normal expression can be used, including being abitrarily nested.

There are more differences, but that should be enough food for the mind to think about it.

You could summarize it as: async/await makes it easier to work with promises on the syntax level and trying to make async code look like sync code, while the do-notation does not try to make async code to look like sync code, but rather embrace that sometimes two different semantical flows are interwined (one inside a monadic context, one pure) and makes it easier to work with them on the syntax level while at the same time making the two look _different_ explicitly.

Re: I Avoid Async/Await

#78
post #29

I never liked promises when they were first introduced because I never perceived this "callback hell" to be an unmanageable problem; there are excellent libraries to manage callback composition, e.g. https://caolan.github.io/async/v3/ When Promises came along I didn't feel they added much value; in fact it made things more complicated (new paradigm, harder to compose). Still, I went with it because everyone else went…

The semantics of the library you link to seems fairly similar/analogous to promises to me! I'd in fact call promises themselves "an excellent library to manage callback composition", I don't see any reason to prefer the one you link over the promises api -- even if neither were built-in to JS. (And promises of course originally were not).

Re: I Avoid Async/Await

#80
I work on a web scripting language that abstracts away asyc/await:

https://hyperscript.org/docs/#async

we call it "Async Transparency"

It lets you write code like this:

  fetch /some-url as json
  put the result's content into me
where fetch is an async call, but you don't have to await it or anything or mark it as being an async fuction, whathaveyou

effectively, we de-color the language:

https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...

my feeling is that async concerns are too low level for light scripting

Post reply on HN