Live data from Hacker News

I Avoid Async/Await

uniqname.medium.com

111–120 of 242 posts

Re: I Avoid Async/Await

#111
post #39

Now maybe it’s just my familiarity with Promises, but I look at the third example and I can quickly see an opportunity. This entire article is built around the author's ignorance and could easily be summarised as "I avoid async/await syntax because I'm more familiar with promises". The author doesn't even appear to understand that async/await is syntactic sugar for promises.

The author even implies in a footnote that switch statements are unusable. I mean, we probably all had painful experience with the “gotcha”, and I appreciate efforts towards safer designs. But I mean, let’s not be ridiculous. It works fine.

Re: I Avoid Async/Await

#112

I always wondered why async/await introduced a concise way of dealing with asynchronous code, but then breaks all this conciseness with try/catch ... Hence I tried to combine async/await with catch for an improved readability [0] two years ago. Turns out I never used this approach, because it's not common sense when working in a team and still feels too verbose. Either one uses then/catch or async/await with try/catc…

I've never found this to be much of a problem in good code. API failures in front-end code tend to fall into a couple of buckets that can be abstracted away. If you want to preserve the page and keep retrying with exponential backoff, you can just implement that as a function that you then await until it succeeds. If you can't recover and just want to show the user a "shit's fucked, refresh the page" banner then you just need one handler near the top of the stack and let the errors bubble up. Most people are working in a declarative environment like React where you can just have a hook wrapping your API calls that exposes a potential error state to render accordingly.

You only really need to have try/catch blocks in 1 or 2 places unless you have a lot of novel async stuff going on that needs to recover from failures in specific ways. Most front-end code shouldn't have a try/catch around every API call.

Re: I Avoid Async/Await

#113
post #86

Earlier quoted context omitted.

const myfunc = () => new Promise(resolve => resolve()) Is there anyone that actually likes this structure? I find it really hard to reason about what a line like this does. What is the upper limit on double arrows in one line?

here's a real world example I use all the time: const wait = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms)); then: async function () { await wait(1000); } Perhaps it's hard to grok but it sure is a handy one-liner. Of course in newer versions of node we can now do: import { setTimeout, } from 'timers/promises'; await setTimeout(100);

this works in older versions of node too:

const wait = require(‘util’).promisify(setTimeout)

Re: I Avoid Async/Await

#114
I don't mind using async/await when I use promises, but in my experience people who never worked with bare promises have a hard time really understanding async/await and will eventually need help from people who did for harder problems. Just like people who never used callback flows often struggle to understand well asynchronicity and mess up with promises.

Re: I Avoid Async/Await

#115
post #10

As a fullstack dev, I worked with - Spring MVC (Java Futures) - Spring Webflux (Reactor observables) - Scala (Scala Futures & for comprehensions) - TS async/await - Angular observables - React hooks (which combined with Redux, React Query etc. is a special approach to async programming.) I think it's very important to understand that ultimately, async (non-blocking) programming is kind of a "hard problem" and there i…

"[..] and the JVM has limited thread count, too" I think I understand you point when it comes to the essentially single threaded Javascript runtime, but the thread limit of the JVM is huge, so how does that matter? Not trying to be pedantic, just wanted to know if I missed something.

Yes, for JVM, it's not that trivial and non-blocking code is definitely not mandatory. Our app backend has been written in a blocking fashion and we are gradually transitioning to non-blocking code.

Your question is very valid as the JVM can handle even thousands of threads (given the host OS can).

Having less threads does keep memory usage lower (as each thread in the thread pool has its own stack space). Also, it's more scalable because if using blocking code execution, you'll need to have one thread per concurrent request served. Lastly, thread starvation can become a problem with blocking code in case of delayed I/O or other failures. If that happens, the server becomes unable to serve new requests.

See this SO answer: https://stackoverflow.com/a/63490797

Re: I Avoid Async/Await

#116

Everytime I use a language with async / await syntax, I find myself wishing that awaiting async functions was the default behavior and that I had to specify when I didn't want that behavior. So much boilerplate, so many times I've seen bugs that are the result of not being aware of a function being asynchronous or that the function was later made asynchronous. Most of the time you want seemingly synchronous behavior…

You may want to check out Zig's async/await. Seems to be closer to what you're suggesting. It's one of the few implementations where functions don't have an "async"/"no-async" color, and where you use the same IO functions regardless of whether you want to use them asynchronously or synchronously (if I remember correctly).

Re: I Avoid Async/Await

#117
post #5

I know the article is about JavaScript, but I was wondering how Swift resolves the problem of weak self within the async/await model. If the part of the function after await is the callback, how do I specify weak self if I need to?

You can generally do something like: Task { [weak self] in await foo() self?.bar() // self may be nil } That is, you can just make a new task which awaits on something and then does more work, and that Task can be tagged with weak self so that self can be freed.

So basically no way to do the same with await, other than of course declaring a weak local var.

Re: I Avoid Async/Await

#118
post #86

Earlier quoted context omitted.

const myfunc = () => new Promise(resolve => resolve()) Is there anyone that actually likes this structure? I find it really hard to reason about what a line like this does. What is the upper limit on double arrows in one line?

It’s the cleanest way to wrap a event-emitting library, for example. async/await is not applicable in such a case where resolve needs to be explicitly called in a callback. async function process() { return new Promise((resolve, reject) => { emitter.on(”error”, (err) => reject(err)); emitter.on(”end”, (result) => resolve(result)); emitter.start(); }); } async is not strictly needed here, but I find it a good practice…

[deleted]

Re: I Avoid Async/Await

#119
post #86

Earlier quoted context omitted.

const myfunc = () => new Promise(resolve => resolve()) Is there anyone that actually likes this structure? I find it really hard to reason about what a line like this does. What is the upper limit on double arrows in one line?

It’s the cleanest way to wrap a event-emitting library, for example. async/await is not applicable in such a case where resolve needs to be explicitly called in a callback. async function process() { return new Promise((resolve, reject) => { emitter.on(”error”, (err) => reject(err)); emitter.on(”end”, (result) => resolve(result)); emitter.start(); }); } async is not strictly needed here, but I find it a good practice…

I don't think it's a good practice, atleast if you have typescript jn your stack. It's redundant and wraps the promise in another promise.

Re: I Avoid Async/Await

#120
post #57
post #39

Now maybe it’s just my familiarity with Promises, but I look at the third example and I can quickly see an opportunity. This entire article is built around the author's ignorance and could easily be summarised as "I avoid async/await syntax because I'm more familiar with promises". The author doesn't even appear to understand that async/await is syntactic sugar for promises.

I avoid Javascript outright because async/await/promise is confusing to me. I blame it on being a PHP Programmer and likes things to run serially.

It drove me crazy too, until I needed to use Puppeteer which requires you to write async/await (there are Puppeteer implementations in other languages, but they all seem to make compromises I didn't want). Generally speaking, async/await allows you to write code that looks and feels serial. Perhaps try using one of the async libraries for PHP to wrap your mind around the concept of async/await (like https://github.com/spatie/async)
Post reply on HN