10 ms·
There are promises there, it just hides it. All async functions return a promise, and `await` works with promises builtin. It's basically the same thing as gene
by jlongster 11y ago
There are promises there, it just hides it. All async functions return a promise, and `await` works with promises builtin. It's basically the same thing as generators, without the `function*` syntax.
Which is unfortunate because async/await only works with promises, and if you want any other async model (like one that doesn't eat errors all the time) you can't use it. Luckily, generators are fine.
- nailer 11y agoThat's correct, I've edited my post to be clearer. Thanks.
- SerpentJoe 11y agoI'm confused, I don't know what type of errors a promise eats. If you're chaining together promises returned by other routines, especially with async/await, then error propagation and handling is very natural. If you're creating a promise using `new Promise` then you can use reject to propagate errors. How does this fall short of other async models?
- grayrest 11y agoThe problem isn't the propagation, it's the propagation by default. He wants errors that occur in development to pop a stack trace as soon as the error occurs without needing to attach a .catch handler.
- spb 11y agoBut... it's an async call. The error is going to happen as part of the event loop. That's inherent to the nature of async. If you want to get the error before it happens, you'll need a time machine.
- colin_jack 11y agoIts not about getting errors before they happen: http://jlongster.com/Stop-Trying-to-Catch-Me http://jlongster.com/Stop-Trying-to-Catch-Me
- nvivo 11y agoThis requires the first method running in the stack to handle the failed promise and rethrow as an exception. It can be done today manually. But with async/await this will be done automatically.
- awalGarg 11y agoI think you you (he?) needs RejectionEvent[0]. If that is so, it is a solved problem :) Basically, implementations log the error to the console and raise the PotentiallyUnhandledRejection event if an error occurs inside a promise and no .catch handler was attached. If a .catch handler is attached _after_ the error is already logged, then a RejectionHandled event is raised. You can listen to those global events (the context is process in node, and window in browser, I think). 0: https://github.com/domenic/unhandled-rejections-browser-spec#the-promiserejectionevent-interface https://github.com/domenic/unhandled-rejections-browser-spec...
- nvivo 11y agoWhat 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.
- jlongster 11y ago> 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. There are proposals to make async/await more composable: https://github.com/jhusain/compositional-functions https://github.com/jhusain/compositional-functions. TC39 is aware of this but I'm not sure if they are going to fix it or not. > 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 http://jlongster.com/Stop-Trying-to-Catch-Me
- nvivo 11y agoPromises 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.
- mmatants 11y ago
- bsimpson 11y agoSo conceptually, async/await is just replacing the `await someMethod()` statement with the first argument to `resolve` or calling `catch()` with the first argument of `reject`?
- nvivo 11y agoAlmost. In simple terms: // this var x = await promise; callSomething(x); // translates as promise.then(x => callSomething(x)); Under the hood, the entire "async" function is turned into a state machine instead of creating a lot of callbacks. It's more efficient it can do some optimizations that would be boring to do manually. For example, if the translation were simply "turn into callbacks", this: var p = getJson(); var x = await p; var y = await p; var z = await p; would translate to something like : var p = getJson(); p.then(o => { var x = o; }); p.then(o => { var y = o; }); p.then(o => { var z = o; }); but instead, the code runs more like this: getJson().then(o => { var x = o; var y = o; var z = o; }); I say runs like because the compiled code is more complex than that, it will still call functions, etc. It will also handle exceptions, which would add a lot of boilerplate to this code. But have in mind that because this is generated by the compiler, this code will in most cases be more efficient than anything you try to write by hand.
- bsimpson 11y agoThanks. So conceptually, it's what I described; but in practice, it's optimized?
- nvivo 11y agoYes. Also, you can read and debug more easily.
- tracker1 11y agoIt also allows for workflows that are really hard with promise chains alone, even if what it does isn't so simple.. while (somecondition) { try { await sleep(1000); somecondition = await someAsyncAction(); } catch(err) { } } Doing retries, or loops against promise actions are really cumbersome with promises directly, but with async/await becomes much more clear in terms of action and intent.
- Sir_Cmpwn 11y agoHow does async/await eat errors? try { await do_thing(); } catch { // works }
- jlongster 11y agohttp://jlongster.com/Stop-Trying-to-Catch-Me http://jlongster.com/Stop-Trying-to-Catch-Me
- Sir_Cmpwn 11y agoI don't really agree with the points this post puts forth, but I also don't really think this is the place to discuss it.
- grandalf 11y agoThis is a great place to discuss it.
- Sir_Cmpwn 11y agoI just didn't want to get into the weeds about why his blog post is wrong here. In any case, his arguments against try...catch are silly. Syntax errors are not an argument against them, because you can easily detect them with other tools (and should be doing so). In practice, the only errors that will bubble up to your try...catch are ones about the async operation, not "typos".
- nvivo 11y agoAbout the points you make on your post, once async/await is implemented in browsers, you will be able to await run() directly, causing the exception to be thrown in the console. The fact that you call a method that returns a promise but don't check this promise may be a little confusing to someone new to the language, but it it's not a flaw in the design. In c#, any attemp to call a method that returns tasks (promise) without an await or a .continueWith (.then) causes a compiler warning. It's just a matter of time for tooling in the browser to keep up.