9 ms·
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
by chmod775 5y ago
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 a certain set of skills (and lack thereof) that would have just as much trouble with bare-bones Promises. But I don't have to because the author did it for me at "One more thing…".
"People can mess this up" was never an argument. You can mess everything up. The more interesting question is how badly and how often.
- eurasiantiger 5y agoThis, very much this. async function() {} is much nicer than function() { return new Promise( (resolve) => resolve() ) }
- bin_bash 5y agoI prefer async/await but this is a contrived example. For starters you can just write: const myfunc = () => new Promise(resolve => resolve()) or Promise.resolve()
- wildrhythms 5y agoAs soon as you need to chain Promises, this gets very annoying and you quickly find yourself in a nested callback hell.
- bin_bash 5y agoIf you’re nesting “new Promise” you’re almost certainly doing it wrong. This is for generating new promises not executing them.
- Aeolun 5y agoconst 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?
- bin_bash 5y agohere'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);
- love2read 5y agothis works in older versions of node too: const wait = require(‘util’).promisify(setTimeout)
- oauea 5y agobut not in the browser
- joe_guy 5y agoThere's no merit of what should be a project wide function being a single line instead of 3 to avoid "hard to grok" syntax.
- deschutes 5y agoWait till you see the rest of javascript...
- eurasiantiger 5y agoYour comment is snarky and categorically dismissive. Care to explain why you have taken such an aggressive stance against JS?
- dataflow 5y agonew 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.
- michaelsalim 5y agoCare to give some examples of the helpers? I always just use new Promise()
- aGHz 5y agoYou really end up creating promises manually, the vast majority are downstream from an IO call like fetch() or a database query.
- eurasiantiger 5y agoMany devs unnecessarily nest Promises like that. async function getData() { return new Promise((resolve) => { const res = fetch(…); resolve(res); }); } The response above is wrapped in THREE different Promises! One from fetch, one manually created, and one implicitly created by `async`. The code above behaves exactly the same as function getData() { return fetch(…); } or even just fetch(…);
- RobertWHurst 5y agoI've been on teams working on node projects for like 15 years. I've never seen someone who understands promises or async await do that. You'd have to know nothing about what the async keyword actually does to be compelled to do that.
- eurasiantiger 5y agoI have seen plenty of (usually junior front-end) devs resort to exactly this kind of cargo cult coding and magical thinking.
- kabes 5y agoI agree but second one could just be `() => Promise.resolve()`
- adamauckland 5y agoIt could, but depending on how you use it, you're changing scoping.
- kabes 5y agoTrue. But these days it's rare to see a scope other than what you'd expect from the short hand version. Old school JS with plain prototypes and flexible 'this' scope is very powerful, but is too hard to understand and thus rare these days.
- eurasiantiger 5y agoThat’s one of the neat things about JS: even outside the prototypal inheritance chain, classes can be (partially) composed of generalized, reusable functions, a bit like traits. Just import a function and bind it in the constructor (call).
- Waterluvian 5y agoTypeScript even forces you to acknowledge this as the explicit return type of an async function is a promise.
- BenoitEssiambre 5y agoAsync/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-await/343 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/Reference/Global_Objects/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 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).
- nameisname 5y agoI don't agree with you fully. Async most certainly always returns a promise and as such can easily be combined with promise functions, like Promise.all. Your understanding of stack traces on promises is also old/uninformed. I work on an enterprise grade node app that was started back in node 0.11. Bluebird, which was what one used, offers good stack tracing and improved stack tracing has been available for async await for a few years now. Infact, I don't think I have had to go out of my way to get a decent stack trace in about a year or more now. There are certain paradigms you can adopt that keeps promise chains clean just like you would adopt with callbacks. I can't comment on if async await was implemented poorly as you are certainly more knowledgeable there with the RFC you shared.
- whatdidiexpect2 5y agoIt’s just another willfully ignorant post by a mediocre JavaScript developer. Are you shocked?
- noahtallen 5y ago
- gotaquestion 5y ago> A lot of the argument appears to be the author extrapolating from his own lack of familiarity to others This is literally 97.5% of all tech blogs, and a disappointing amount of content on HN front page. I feel bad for the author. Nothing like asserting your ignorance on a blog. There's a time and a place for literally every language construct.
- gompertz 5y agoAgreed, and I think some authors need to be more humble. If a construct or design choice exists, its far more likely someone (or a team) spent hundreds more hours intentionally reasoning for its existence in the first place; over your passive duration of usage.
- spankalee 5y agoasync/await is _safer_ too, because part of that syntactic sugar is wiring up exceptions correctly and ensuring that a function only returns or rejects asynchronously and never synchronously. This prevents lots of bugs. This article is bad, bad advice.
- phendrenad2 5y ago> 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 Sounds like you didn't understand the point of the article. Unfortunately, you're arguing against something the author never said, the author never said that async/await weren't promises. You just got stuck on the fact that the author used the term "promise" for the non-async/await style of code. I understood what the author meant, anyway. > "People can mess this up" was never an argument Unfortunately, you're arguing against something the author never said here, also. The author is saying that non-async/await code is better code than async/await. Not that "people can mess this up" or something.
- chmod775 5y ago> Sounds like you didn't understand the point of the article. Unfortunately, you're arguing against something the author never said, the author never said that async/await weren't promises. Well. I never said that I didn't understand the article. Unfortunately you are arguing against something I never said. Funny how that works. > The author is saying that non-async/await code is better code than async/await. And what does "better" mean to the author? The entire first section is devoted to the author talking about criteria such as "brittle"-ness, "error-prone"-ness, and "footguns". You seem to be getting stuck up on the fact that the author never used the exact same wording as I did.
- mananaysiempre 5y ago> The point of async/await is not to never have the word "Promise" appear in your code. Indeed it is not the point, and in that sense your criticism of the article is correct. However, there are people who argue[1] that it is, in fact, a good thing to never have the word "Promise" appear in your code, that not having the freedom to execute whatever code you want after launching an asynchronous operation and instead having the predictability of always returning to the scheduler makes reasoning about asynchronous code much simpler. (For one thing, you can now reliably think—and have syntactic support for thinking—in terms of sequential coroutines with predictable yield points and known parents.) In the context that Smith refers to (trio vs asyncio in Python, regarding which also see the first, more Python-specific but IMO better-argued post[2]) my experience actually bears that out. How well this works given the historical API baggage in JavaScript, I don’t know, but probably not very well. Another curious thing is that the line of research JavaScript promises originate from[3] (Mark Miller co-wrote the spec proposal IIRC) does not use them as the user interface; instead, using the "eventual send"[4], you queue up method calls to objects (which can be promised results of other queued calls, and you may pass other promised objects as arguments). I cannot clearly articulate the relation of this to Smith’s notion of “structured concurrency” (I wish I could), but in any case it contributes some more weight to the opinion that the ergonomics of Promises are indeed subpar. It might well be, though, that in the context of JavaScript you can’t actually enforce enough structure on the preexisting APIs to build a superior alternative. [1] https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ https://vorpus.org/blog/notes-on-structured-concurrency-or-g... [2] https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/ https://vorpus.org/blog/some-thoughts-on-asynchronous-api-de... [3] http://erights.org/talks/thesis/index.html http://erights.org/talks/thesis/index.html [4] http://erights.org/elib/distrib/pipeline.html http://erights.org/elib/distrib/pipeline.html