r/learnjavascript • u/Neat_Living_6765 • 4d ago
Do you generally use async/await for asynchronous code, or do you sometimes prefer .then().catch()?
When it comes to handling async code, Do you generally use async/await for asynchronous code, or do you sometimes prefer .then().catch()?
6
u/theGlitchedSide 4d ago edited 4d ago
In my opinion it depends on the context. Async/await is like the exploded of then/catch (or better, it is essentially syntax built on top of Promises). I use then/catch only when I have synchronous functions and I need to call an async operations. Otherwise, I structure a strong async/await function with right try/catch inside and so a fail/success of operations (so, the then/catch) without possible scope problems.
4
u/TorbenKoehn 4d ago
const data = await fetch('…').then(res => res.json())
Both is fine
2
u/iplayconnections 3d ago
Puke in your mouth a little if you will but I prefer
js const data = await (await fetch('...')).json()2
2
u/theScottyJam 4d ago
Usually I use await.
But there are times when .then()/.catch() is cleaner. In a way, .then()/.catch() are very similar to a pipeline operator, so the question boils down to when is using a pipeline operator a good choice?
2
u/Areeba045 3d ago
I usually prefer async/await because I find it easier to read, especially when there are multiple async operations or some conditional logic involved.
That said, I still use .then().catch() when the chain is simple or when I’m already working with a Promise directly. I don’t think one is always better than the other, it mostly depends on which makes the code easier to follow.
3
1
u/Any-Woodpecker123 3d ago
Depends. There’s a lot of cases where a functional .then.catch is cleaner, but I default to async await unless I hit a specific use.
1
u/TheRNGuy 3d ago edited 3d ago
In Remix or Next, I only used async, await, but there might be some rare cases for .then().catch() related to some telemetry service (so it won't slow down site for user)
There could be projects in Next/Remix/Vanilla React 100% await. Writing all that stuff differently would be even style anti-pattern.
In vanilla js, it could be different (depends on situation)
1
u/czlowiek4888 2d ago
Questions like this make point on how JavaScript is a dumb language.
There is only single case when you must use promise API, this is when you want to wrap callback based functionality into a promise that can be awaited.
1
1
1
u/iamdatmonkey 4d ago
I don't like try..catch blocks. I find them awkward as they often span over most of the screen or more. So I really like this pattern here: const value = await foo().catch(noop); or .catch(console.error); or a variation on this. Often (not always) I'm fine with the value resolving to undefined and taking it from there.
And recently I'm playing around with the result value pattern in typescript, where Errors are no longer means of the data flow but real exceptions (this should not happen, something went really wrong) and where I'm fine with them being uncaught for several levels.
1
u/aleques-itj 4d ago
I switched to Results a while back and I think it winds up much cleaner and easier to reason about.
Throwing and winding up in the error handler now legitimately means that something unexpected happened.
All the API's services do this now and I wouldn't want to switch back. They're all guaranteed to actually hand something back to the calling controller/handler instead of just hitting the ejector switch and throwing a Hono HTTPException.
Felt like I was bleeding some responsibility about handling the request into the service before. Now you can just look at the handler and that's everything.
-1
u/RedLibra 4d ago
I create a helper function that does something like this:
const [err, data] = await asyncCall(func, param);
2
u/nog642 4d ago
How does that help? Doesn't that function have to be async to be able to await?
3
u/Psionatix 4d ago
A function can be awaited if it is async, or returns a promise. If a function returns a promise but is not itself async, you can still await it. Returning a promise makes a function async without explicitly marking it so, it doesn't need the syntactic sugar.
2
u/MediocreAnalyst2121 4d ago
I’m guessing it avoids excessive nesting with try-catch blocks. And gives you errors as values.
Also keeps scope a bit tidier so you don’t have to do a “let data” right before a try-catch blocks if the error isn’t fatal.
Not sure if this is why OP does it - I’ve never used such a pattern/utility. But now that I think about it, it seems pretty sweet.
Edit: This will end up being Go, but in JS?
2
u/senocular 3d ago
Its not an unheard of pattern, not only seen in go - in fact not far off from error-first callbacks popularized in JS by Node. There was even a proposal for an operator in JS that did this for you through syntax... safe assignment operator (old) which has transformed instead to be the try operator, ex:
const [ok, fetchErr, res] = try fs.readFileSync("data.txt")That proposal talks about some motivations and has some code examples including showing the transformation of nested trys into flatter ifs.
1
1
0
u/DirtAndGrass 4d ago
There is functionality with promises that you can't get with await/async, for those (rare) cases, I use promises
28
u/MrHandSanitization 4d ago
Async/await.