> The three horsemen of unmaintainable JavaScript have always been generators, RxJS, and Redux.
Redux produces the easiest to follow code when following best practices. It’s boring and works extremely well for its purpose.
Generators may get a bad wrap but async/await are just generators with a different syntax — at least in js land. Would you argue the same for async/await?
I’ve seen this comparison to async/await a few times and I’m not sure how accurate it actually is. It’s true that async functions can be polyfilled via generators, but from what I understand that’s more of a conceptual transpilation by tools like Babel, rather than a runtime implementation.
IMO the `await` keyword is clever abstraction that can make asynchronous code easier to understand in a synchronous way. And unlike the collection-oriented ceremony of generators, calling await on an expression doesn’t imply anything more than the presence of a `then` method on an object.
Anything with a `then` method can be awaited, and so native Promises aren’t actually all the special or sacred. Invoking await on an expression involves no extra machinery, only that a Promise-like object is returned.
And the `async` keyword is even better. It’s completely optional! This keyword only has two effects: allowing the `await` keyword in a function scope, and implicitly returning a promise.
There’s a secret pleasure in all this too. A series of awaited Promises can be wrapped into a single async function. And there’s no need for multiple error checking steps either. All async functions return a promise, so we can wrap the function single try/catch block, or even daisy-chain another promise on the `catch` method. All the pieces fit into each other, and most of them are optional.
Meanwhile in generator land, we’ve got cognitive overload in spades. Yield can only be called from inside a generator, yes that little asterisk next to the function name you might at first glance mistake for an errant multiplication symbol. Sorry, there’s these things called Symbols too. Any object can be made yieldable…or was it iterable…by placing the special symbol on an object class as an interpolated method which returns an iterable. I’m not making this up.
Imagine teaching this to a junior developer who’s spent over a year programming asynchronous code and never once needing a generator. The tide-level for problems solved with generators is always waist-deep, always introduced as a secondary step to achieving another goal.
Generators are almost always hints of a design-flaw introduced much earlier in development, usually by an engineer with enough experience to write code, but not nearly enough to understand how it works.
> Anything with a `then` method can be awaited, and so native Promises aren’t actually all the special or sacred. Invoking await on an expression involves no extra machinery, only that a Promise-like object is returned.
Huh wow! I did not know that! I think TypeScript always kept this hidden from me, but it makes sense. Another perk of `await` is that it collapses all promises into their final value, regardless of how many nested pending promises are expressed:
Redux produces the easiest to follow code when following best practices. It’s boring and works extremely well for its purpose.
Generators may get a bad wrap but async/await are just generators with a different syntax — at least in js land. Would you argue the same for async/await?