clean-code-javascript icon indicating copy to clipboard operation
clean-code-javascript copied to clipboard

Disagree that Async/Await are even cleaner than Promises

Open talJoffeExelate opened this issue 4 years ago • 4 comments

This was not covered in the book and you did not explain how the concepts in the book apply to this use case.

I think using promise chaining is cleaner because it reduces the need for unnecessary intermediate variables (in this case body) and the need for wrapping the code with Try/Catch.

If you would have written it like this:

get("https://en.wikipedia.org/wiki/Robert_Cecil_Martin") .then(body => writeFile(body)) .then(() => logFileWasWritten()) .catch(err => handleError(err));

I think it would be cleaner than the approach below because it is more declarative, fewer lines of code and without intermediate variables. (and you can even extract the arrow functions to a variable)

try { const body = await get( "https://en.wikipedia.org/wiki/Robert_Cecil_Martin" ) await writeFile("article.html", body); logFileWasWritten() } catch (err) { handleError(err) } }

Another small note

body => { return writeFile("article.html", body); }
should have been: body => writeFile("article.html", body)

talJoffeExelate avatar Jan 19 '20 12:01 talJoffeExelate

I second this I would also argue they are safer because you dont have to remember to wrap your code in try catch and although promises dont cause runtime errors they do log to the console so if you gave forgotten to catch you will be notified.

Pingid avatar Jan 21 '20 11:01 Pingid

I think although you might be able to point out a few instances where the .then syntax makes more sense; in reality async/await is a much more cleaner syntax. Usually programs looks more like this.

const user = await userPromise(id);
if (user.postCount > 0) user.posts = await getUserPosts(user.id);
// using .then
const user = userPromise(id),then((user) => {
   if (!user.postCount) return Promise.resolve(user)
   return getUserPosts(user).then(posts => { user.posts = posts; return users});
}) 

this is with just statement. but you see the problem.

noelzubin avatar Feb 19 '20 05:02 noelzubin

Disagree with title...

To add just my 2cents to the discussion: callback style and their replacement with Promises were a nightmare for beginners to learn, this by itself already gives you hints that they weren't exactly the best approach in the first place. In fact, I believe that the async/await style brought a breath of fresh air to javascript again, giving newbies and developers from other languages a common and expected base to work on.

Eitz avatar Jun 30 '20 13:06 Eitz

While I think async-await is a nice syntax that sometimes indeed increases readability, it's not a golden hammer that can be used everywhere. async-await makes you write imperative-style code, which is generally fine, because in such code you deal with side effects anyway, and synchronous-looking code as well as try-catch blocks are easier to read in some cases. Functional-style code (that Promises make you write) however is better composable (and you can use Promise.all(), for example), so if that's what you need, your code might be more readable that way. As a sidenote, RxJS introduces the Observable concept as a generalization of Promises (with the ability to convert them), which provides even more composability in the functional style.

Therefore you should:

  • Use async/await when you need more straightforward, synchronous-looking code and easier-to-understand error handling.
  • Use Promises when you need better composability or when wrapping async callbacks into Promises.

So in projects you will generally see a mix of both.

rkrisztian avatar Sep 01 '23 13:09 rkrisztian