4 ms·
Curious - did anyone look at the first example and not immediately see that the requests would occur in series? IMO the “await” actually makes this much more ex
by jakear 6y ago
Curious - did anyone look at the first example and not immediately see that the requests would occur in series? IMO the “await” actually makes this much more explicit.
- zwieback 6y agoYeah, I couldn't understand what the article was about until the end because it's so obvious that the requests would not be in parallel.
- oauea 6y agoIt reads like it might be this guy's first week, this is extremely obvious. Confused why this has so many upvotes.
- pixelbath 6y agoYes - I thought that perhaps "await" did something different in JS than C#, but that is literally its entire purpose: to synchronously wait for a call within an asynchronous method. Even Wikipedia says the async/await pattern "allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function." Honestly not sure how this made it to even 20 points.
- crazygringo 6y agoCompletely. I had no idea what the "problem" was because it was so obvious that the intention of the code was to have them run sequentially. Next up: exception handling doesn't work if you never catch exceptions! Followed by, assigning a pointer to another variable doesn't assign the value the pointer points to! :P
- norswap 6y agoExactly, it's called AWAIT damn it. It's also behaves like synchronous I/O, which is the whole point of the notation. Which isn't to say all is rosy in async/await world. Debugging them (in JS in particular) is particularly painful.
- throwaway43234 6y agoWhat do you find painful about it? Have you tried the new vscode javascript debugger? It makes things fairly easy - I'd say the main issue is loss of local variables in async stack frames (which makes sense, unless they're closed they're gone), but that's not typically too big of a concern IMO.
- eska 6y agoDebugging those got a lot better in the new Firefox dev tools.
- happytoexplain 6y agoAbsolutely. I don't even write JS and I couldn't understand what point he was trying to make until he said it: That it was somehow not obvious that `await`... awaits?
- brundolf 6y agoI think many newer developers, especially ones who are naive to asynchronous programming, may learn/be taught that "when you want to get a result from an API, you just need to put 'await' in front of it", without fully understanding what exactly it entails. There may be fewer people in that situation on HN than there are in the developer population at large, but I theorize that it's a widespread issue and I wanted to shed some light on it.
- TheCoelacanth 6y agoThat's true, but in my experience, they also just memorize the ".then(result =>" pattern and make exactly the same mistake.
- brundolf 6y agoBut I maintain that in the illustrated case - where you want to get all the different independent values and then combine them at the end - it's actually less ergonomic to do it the wrong way with .then(...) than it is to do it the right way.
- jakear 6y agoMost ergonomic IMO is: const getPeople = async () => (await Promise.all(...)).flat() Without await this would be const getPeople = () => Promise.all(...).then(arrs => arrs.flat()) The difference is slight to be sure, but I usually prefer the await approach.
- faizshah 6y agoI did have this misunderstanding when relearning Promises and Async/Await in JS. The misunderstanding is actually not about await but about when a Promise is executed. The question you ask yourself when learning Promises is why calling await on a promise directly vs calling it on a variable containing a promise is different. Of course the root cause of the misunderstanding is not understanding Promises are executed immediately and await blocks on a promise. So creating a promise after an await causes the second promise to be executed after the awaited promise is resolved. For me I still had my mental model from a lazy execution environment (Dask) and that’s where my misconception came from.
- jakear 6y agoThanks for the contrarian perspective. Agree that if ones mental model of JS execution is flawed there will be confusion, but I’m not sure that is really reason to “beware of async/await”.
- akiselev 6y agoIt's a common problem with many languages - I've experienced it recently myself with Rust's futures. It requires you to be explicit about spawning tasks since that requires a heap allocation and it took me a while to figure out that I had to explicitly include an async runtime (of which there are several) and start up the async tasks myself. That said, I agree with the GP. I immediately saw that it was going to execute sequentially and thought nothing of it. Most of the time I use async/await not for concurrency but for syntax sugar and to get proper exceptions from promise based APIs instead of the GOTO FAIL control flow breaking nonsense that is catch().
- steveklabnik 6y agoIt doesn't inherently require a heap allocation, but the common, non-embedded use case does.
- akiselev 6y agoYeah I was glossing over the specifics for this context. The way futures/generators are implemented as syntax sugar over a closure/state machine that can live on the stack is one of my favorite features of Rust, but i.e. an executor that uses a smallvec task queue is a bit esoteric for a discussion that started around Javascript.
- thiht 6y agoI never used async/await as I'm more comfortable with promises so yeah, I thought the first code was correct. async/await is clearer to me after reading this article though.
- zenexer 6y agoIt was immediately clear that it was sequential. Given that the name of the function is “getPeople,” I figured that was probably the mistake the author was pointing out, but it was quite obvious. And I’m not really a JavaScript developer. This is a fairly common mistake, but it’s also easy to spot.