What do you mean by "if you want any other async model you can't use it"? I know you can write whatever code you want, but promises are supposed to be the standard way of signaling completion of asynchronous operations in javascript.
This is the same as saying that "arrow functions only works if you want to represent functions".
Also, promises don't eat errors. It's the code using those promises that forget to handle them.
The async/await fixes that by unwrapping those errors for you. Any errors in an "await expression" will be thrown as exceptions up the stack.
> What do you mean by "if you want any other async model you can't use it"?
Promises are not the only way to do async work in JS, as much as some people like to say that. You have observables and channels, which are more powerful because they handle streaming.
> Also, promises don't eat errors. It's the code using those promises that forget to handle them.
They literally do. They run your code in a try/catch block and store the error away, and you have to remember yourself to manually throw it later. You shouldn't be forced to run code inside a try/catch. http://jlongster.com/Stop-Trying-to-Catch-Me
>I don't care about awkward .then() syntax. I don't mind automatic error propagation. I don't care having to call .done() on a promise chain. I don't care about losing the stack (which is inherent in any async work). I care that promises grab all errors, just like try/catch.
You should stop caring about that and start caring about the other stuff.
"Breakpoint on exception" still works, albeit slightly altered, and in any way it's a minor detail compared to the far better mental model for code execution that async and promises bring.
>I want to make stupid typo errors and have them appear as normal errors, not caught by promises.
For stupid typo errors use a linter and/or a transpiler like babel in the first place.
>It's cool, I just don't understand why everyone is so excited about a simple syntactic improvement.
Because better syntax brings code closer to how we think, and reduces errors.
In some way, promoting the use of "await" actually reduces the chance of an exception floating away into the ether. The "thread" joins back, both on success and on failure. And because promise errors are like exceptions, it's probably not a great idea to signal commonly-occurring conditions through them (instead using sentinel values like nulls, etc); so there isn't a huge pressure to try-catch every single thing.
Also, there is fundamentally nothing wrong with a promise error that never gets handled. It's an "if a tree falls in the woods" kind of thing, no? I will concur that it's not exactly beginner-friendly, though.
Promises and observables are related but operate differently, just as a single string relates to an array. Promises represent a single operation, there is nothing wrong with the abstraction itself.
As for the errors, I see what you mean. But at the same time this is an issue with trying to write async operations with sync constructs, something all "old" languages need to do. Async/await is a pattern that does that in languages that can't do it implicitly by requiring an explicit declaration. You don't need to write try/catch with async/await. You will get the exception propagated through the stack automatically.
«They run your code in a try/catch block and store the error away, and you have to remember yourself to manually throw it later.»
Browser native Promises and their corresponding Dev Tools work exactly how you would expect and surface uncaught exceptions in Promises. Browsers that support async/await will especially be incentivized to provide strong asynchronous exception handling in their Dev Tools.
It's just tough to polyfill that behavior without bringing the JS synchronous code world to a halt. A good Promises library/polyfill will at least attempt to console.log uncaught exceptions when they happen.
> Promises are not the only way to do async work in JS, as much as some people like to say that. You have observables and channels, which are more powerful because they handle streaming.
Let me just try and translate that into sync-land: "Single value variables are not the only way to do work in JS, as much as some people like to say that. You have arrays and queues, which are more powerful because they handle multiple values"
(my point being, different abstractions are useful for different things and/or in different ways)
> You shouldn't be forced to run code inside a try/catch.
How is throwing on typos useful? The real solution for that isn't letting errors get through. Its having a type system like TypeScript or Flow plus using a sensible library like bluebird that reports rather than swallows up unhandled errors by default. Afaik errors from native promises are reported to the console in most browsers. And there are also tools like this: https://github.com/emberjs/ember-inspector/wiki/Promises-Tab
Allowing thrown errors to propagate synchronously will destroy many contractual guarantees that make promises useful in nodejs. For example, we would have to remove this entire section in Bluebird: https://github.com/petkaantonov/bluebird/blob/master/API.md#... and instead fall back to process crashing and restarting. Lack of error catching is what makes node unable to provide a safe solution to the crashing problem (and domains capture errors in both directions of the call stack which leads to problems inside node internals). Promises neatly solve that by providing a sensible error capturing and propagation model that isolates node internals from promise code: https://github.com/petkaantonov/bluebird/issues/51
This is the same as saying that "arrow functions only works if you want to represent functions".
Also, promises don't eat errors. It's the code using those promises that forget to handle them.
The async/await fixes that by unwrapping those errors for you. Any errors in an "await expression" will be thrown as exceptions up the stack.