3 ms·
The reason why async/await is a good fit for Javascript is that it neatly wraps up asynchronous callback hell and Promises, which were already ubiquitous in Jav
by gridlockd 6y ago
The reason why async/await is a good fit for Javascript is that it neatly wraps up asynchronous callback hell and Promises, which were already ubiquitous in Javascript code, because the web runtime enforces non-blocking IO.
- spanhandler 6y agoNever should have had to worry about that stuff to begin with, unless you were actively using it. I’ve read and written way more code that had to wrestle async back to sync than code that’s actually been able to let async happen at the local scope. Of course if you’re working in a framework (Express, say) one might expect that it would run your entire mostly-sync pile of code async, so it can hop over and process another request. And that’s fine. That’s how it should have worked. Most things should execute in an async context so other things can happen while they’re waiting on IO or whatever, but within them async behavior should have been what required a keyword or a bunch of hideous nesting or whatever.
- pansa2 6y agoDo Promises and async-await work together better than, say, Promises and Lua-like stackful coroutines?
- z3t4 6y agoI dont know Lua, but async/await in JavaScript is syntax sugar for a coroutine.
- WorldMaker 6y agoThis description is probably far more abstract than most would like (and it is probably wrong by not being exact enough, I am not a mathematician I am a software developer), but might be useful to some: coroutines are a join calculus and Promises are a monad. async/await is syntactic sugar for a monad (less general than Haskell's do-notation, more general than only Promises, though rarely in practice used much beyond Promises). You could plumb Promises on top of coroutines easily (and while JS engines are more traditionally event loops; other languages that support async/await such as Python use much more coroutine-like underbellies), and while you don't get the full "join calculus" power/flexibility by putting the monad abstraction on top of the join calculus, you get the benefit of monad transformers like async/await. Those benefits being that the async/await syntax and semantics for working with Promises more closely resembles the imperative code it replaces, whereas the join calculus is its own [sometimes easy, admittedly] learning curve with its own syntax and semantics. Most of the complaints about Promises are the usual complaints about monadic wrapping types that the types become "viral" and "color" all associated code. But that just means that the failure cases are more easily picked up by a static type checker than semantic failures in learning the join calculus.
- wruza 6y agoIt may be the reason, but not the only option. function cpsfoo(cb) {...} function foo() { var thread = this_thread() cpsfoo(x => thread.resume(x)) return thread.yield() } Error and immediate cb invokation handling omitted for clarity. Similar wrapper or wrapper-generator (uncps(f), unpromise(f)) may be done for other primitives.
- merb 6y agowell coroutines are a way better option and working way better than promises, unfortunatly promises were introduced since it's easier to convert a callback function to a promise based one
- gridlockd 6y agoSure, it's not the only option, just the better option for Javascript. Your example isn't representative of Javascript. This is an example for something that might come up in Javascript, using async/await: const a = await fetchA(); const b = await fetchB(a); const stuff = await fetchStuff(a, b); const transformedStuff = await Promise.all(stuff.map(someAsyncTransform)); Error handling is just try/catch. Note that you generally have no control over most of these function being asynchronous. Threads or coroutines do nothing to help you write straightforward code when all your libraries are based on fine-grained callbacks/promises. Writing out that chain of dependencies in CPS would be a nightmare.
- anonymoushn 6y agoThey really do though. In the modal case you would just write the same code as in js but without all the extra keywords. If you need fanout you'd call some special function to do that, like you do now.
- cookiengineer 6y ago> Error and immediate cb invokation handling omitted for clarity. ... but this is exactly the reason why callback hell existed. Error handling down the callback branches were a total mess, especially with networked state transfers.