4 ms·
I was super excited about async/await when it first came out. I hadn't really understood the point of Promises, but async/await looked simple and useful. Howe
by dlbucci 9y ago
I was super excited about async/await when it first came out. I hadn't really understood the point of Promises, but async/await looked simple and useful.
However, I recently started using async/await in TypeScript, and the result seems to be try/catch statements everywhere. Code using async/await seems to be more verbose and unruly than just sticking to Promises, which I now appreciate the elegance of much more (callee convenience/error delegation).
I think I'm just going to stick to Promises for the time being, until I see some hidden usefulness of async/await syntax (which could totally happen. It took me a long time to realize how awesome promises are).
- zackify 9y agoYou can abstract your try / catch logic to a higher level to fix this easily. make all promises extend from a base promise function that either returns a result, or null (or an error, you can make it more complex). Then, let data = await customPromise() if(!data) return this would be better in my opinion that try catch everywhere. Inside that higher order promise you can catch and handle errors.
- pier25 9y agoI'd rather user try/catch than endless chains of then().
- sharemywin 9y agoandThen()...andThen()...andThen().andThen().andThen();
- koolba 9y ago> However, I recently started using async/await in TypeScript, and the result seems to be try/catch statements everywhere. Why do you have try/catch everywhere? Unless you're actually going to handle the error, you shouldn't do anything as it will bubble up till it gets to a piece of the app that can handle it. For web apps a lot of the time that's a single request level handler to return a 5XX. > Code using async/await seems to be more verbose and unruly than just sticking to Promises, which I now appreciate the elegance of much more (callee convenience/error delegation). Eh? Besides the addition of the "async" keyword on the top level function, it's always less verbose. Where I think things get a bit tricky is awaiting the composition of Promises to support parallel processing (as opposed to just 1) await foo() 2) await bar() ...). It's best to treat that like regular composition and simply await the result.
- treve 9y agoThis makes little sense. You don't need more try..catch blocks than you would normally have a catch promise clause. Exceptions bubble up.
- duncanawoods 9y agoI'm finding that with client side async, the awaited behaviour is often external, heterogeneous and unreliable. When an operation fails, it typically requires a state-machine transition to a failed/retry state or fallback service rather than just bubbling up to a top level handler like a coding error i.e. there is something specific you need to do unlike typical exceptions. Retrofitting a code base with async I concur that local try / catch has been necessary and has added code complexity and doesn't always feel like an improvement. In contrast, server side async has been much more elegant because the errors with internal async server operations are much more exceptional and don't require so much case specific handling.
- codedokode 9y agoYou should make your API client layer be able to retry operations (and maybe track the status of a network connection) rather than write catch/then() manually.
- duncanawoods 9y agoIt would be nice if it was that easy but if retry behaviour is dependent on the specific operation attempted and the error information in the response then you need some degree of local handling even if its just to prepare information for a generic handler. Exceptions work best when the error is fatal for the local scope but responses from external services aren't like that. The general problem is that the dividing line between errors and information becomes too blurry - your error might only be information to me. A simple example is where something like axios will (by default) throw on 404 responses but an external api might use 404 to indicate a resource does not exist. If your app logic makes a decision based on this information, you will find yourself using exception handlers for control flow despite not experiencing any actual errors.
- raquo 9y agohmm were you previously using Promise.catch for flow control? It's basically as bad as using exceptions for flow control, just with with a different set of bubbling / propagation problems. Unless you're dealing with truly exceptional conditions you should not be throwing inside your promises, thus no need for try / catch when converting them to async/await.
- lobster_johnson 9y agoRejection is turned into an exception with "await", though. And rejection is perfectly normal with, say, network I/O.
- raquo 9y agoWell yes, that's a reasonable use case. Personally I'm not convinced that all 4xx responses should be rejections, but regardless of that, you should have about as many `catch` blocks with async-await as you have with promises.
- tracker1 9y agoIf you're awaiting/catching upstream, you don't need to wrap at the lower level, and it can be cleaner. const delay = ms => new Promise(r => setTimeout(r, ms)); async function fooErrors() { await delay(100); throw new Error('I failed'); } async function doSomething() { await fooErrors(); } async function main() { try { await doSomething(); } catch(err) { log.fatal(err); } }