【转】6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)

原文:https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9

----------------------------------------------------------------------------------------------

6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)

In case you missed it, Node now supports async/await out of the box since version 7.6. If you haven’t tried it yet, here are a bunch of reasons with examples why you should adopt it immediately and never look back.

[UPDATE]: Node 8 LTS is out now with full Async/Await support.

[EDIT]: It seems that the embedded code on gist does not work on medium native app, but it works on mobile browsers. If you are reading this on the app, tap on the share icon and choose “open in browser” in order to see code snippets.

Async/await 101

For those who have never heard of this topic before, here’s a quick intro

  • Async/await is a new way to write asynchronous code. Previous options for asynchronous code are callbacks and promises.
  • Async/await is actually built on top of promises. It cannot be used with plain callbacks or node callbacks.
  • Async/await is, like promises, non blocking.
  • Async/await makes asynchronous code look and behave a little more like synchronous code. This is where all its power lies.

Syntax

Assuming a function getJSON that returns a promise, and that promise resolves with some JSON object. We just want to call it and log that JSON, then return "done".

This is how you would implement it using promises

const makeRequest = () =>
  getJSON()
    .then(data => {
      console.log(data)
      return "done"
    })

makeRequest()

  

And this is how it looks with async/await

const makeRequest = async () => {
  console.log(await getJSON())
  return "done"
}

makeRequest()

  

There are a few differences here

  1. Our function has the keyword async before it. The await keyword can only be used inside functions defined with async. Any async function returns a promise implicitly, and the resolve value of the promise will be whatever you return from the function (which is the string "done" in our case).
  2. The above point implies that we can’t use await in the top level of our code since that is not inside an async function.

3. await getJSON() means that the console.log call will wait until getJSON() promise resolves and print it value.

Why Is It better?

1. Concise and clean

Look at how much code we didn’t write! Even in the contrived example above, it’s clear we saved a decent amount of code. We didn’t have to write .then, create an anonymous function to handle the response, or give a name data to a variable that we don’t need to use. We also avoided nesting our code. These small advantages add up quickly, which will become more obvious in the following code examples.


2. Error handling

Async/await makes it finally possible to handle both synchronous and asynchronous errors with the same construct, good old try/catch. In the example below with promises, the try/catch will not handle if JSON.parsefails because it’s happening inside a promise. We need to call .catch on the promise and duplicate our error handling code, which will (hopefully) be more sophisticated than console.log in your production ready code.

Now look at the same code with async/await. The catch block now will handle parsing errors.


3. Conditionals

Imagine something like the code below which fetches some data and decides whether it should return that or get more details based on some value in the data.

Just looking at this gives you a headache. It’s easy to get lost in all that nesting (6 levels), braces, and return statements that are only needed to propagate the final result up to the main promise.

This example becomes way more readable when rewritten with async/await.


4. Intermediate values

You have probably found yourself in a situation where you call a promise1and then use what it returns to call promise2, then use the results of both promises to call a promise3. Your code most likely looked like this

If promise3 didn’t require value1 it would be easy to flatten the promise nesting a bit. If you are the kind of person who couldn’t live with this, you could wrap both values 1 & 2 in a Promise.all and avoid deeper nesting, like this

This approach sacrifices semantics for the sake of readability. There is no reason for value1 & value2 to belong in an array together, except to avoid nesting promises.

This same logic becomes ridiculously simple and intuitive with async/await. It makes you wonder about all the things you could have done in the time that you spent struggling to make promises look less hideous.


5. Error stacks

Imagine a piece of code that calls multiple promises in a chain, and somewhere down the chain an error is thrown.

The error stack returned from a promise chain gives no clue of where the error happened. Even worse, it’s misleading; the only function name it contains is callAPromise which is totally innocent of this error (the file and line number are still useful though).

However, the error stack from async/await points to the function that contains the error

This is not a huge plus when you’re developing on your local environment and have the file open in an editor, but it’s quite useful when you’re trying to make sense of error logs coming from your production server. In such cases, knowing the error happened in makeRequest is better than knowing that the error came from a then after a then after a then …


6. Debugging

Last but not least, a killer advantage when using async/await is that it’s much easier to debug. Debugging promises has always been such a pain for 2 reasons

  1. You can’t set breakpoints in arrow functions that return expressions (no body).

Try setting a breakpoint anywhere here

2. If you set a breakpoint inside a .then block and use debug shortcuts like step-over, the debugger will not move to the the following .then because it only “steps” through synchronous code.

With async/await you don’t need arrow functions as much, and you can step through await calls exactly as if they were normal synchronous calls.


In Conclusion

Async/await is one of the most revolutionary features that have been added to JavaScript in the past few years. It makes you realize what a syntactical mess promises are, and provides an intuitive replacement.

Concerns

Some valid skepticism you might have about using this feature

  • It makes asynchronous code less obvious: Our eyes learned to spot asynchronous code whenever we see a callback or a .then, it will take a few weeks for your eyes to adjust to the new signs, but C# had this feature for years and people who are familiar with it know it’s worth this minor, temporary inconvenience.
  • Node 7 is not an LTS release: Yes, but node 8 is coming next month, and migrating you codebase to the new version will most likely take little to no effort. [UPDATE]: Node 8 LTS is now out.

原文地址:https://www.cnblogs.com/oxspirt/p/9768060.html

时间: 2024-10-08 12:04:18

【转】6 Reasons Why JavaScript’s Async/Await Blows Promises Away (Tutorial)的相关文章

理解 JavaScript 的 async/await

随着 Node 7 的发布,越来越多的人开始研究据说是异步编程终级解决方案的 async/await.我第一次看到这组关键字并不是在 JavaScript 语言里,而是在 c# 5.0 的语法中.C# 的 async/await 需要在 .NET Framework 4.5 以上的版本中使用,因此我还很悲伤了一阵--为了要兼容 XP 系统,我们开发的软件不能使用高于 4.0 版本的 .NET Framework. 我之前在<闲谈异步调用"扁平"化> 中就谈到了这个问题.无论

【前端_js】理解 JavaScript 的 async/await

async 和 await 在干什么 任意一个名称都是有意义的,先从字面意思来理解.async 是“异步”的简写,而 await 可以认为是 async wait 的简写.所以应该很好理解 async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成. 理解 JavaScript 的 async/await 原文地址:https://www.cnblogs.com/leiblog/p/11057896.html

[转] Understanding JavaScript’s async await

PS:Promise的用处是异步调用,这个对象使用的时候,call then函数,传一个处理函数进去,处理异步调用后的结果 Promise<Action>这样的对象呢,异步调用后的结果是一个Action,传到处理函数里 async/await的作用是,不需要写then函数了,相当于与自动帮你写,你只需要把异步调用后的结果保存下来就可以了 https://ponyfoo.com/articles/understanding-javascript-async-await http://liubin

JavaScript 的 Async\/Await 完胜 Promise 的六

参考:http://www.10tiao.com/html/558/201705/2650964601/1.html Node 现在从版本 7.6 开始就支持 async/await 了. 简介: Async/await 是一种编写异步代码的新方法.之前异步代码的方案是回调和 promise. Async/await 实际上是建立在 promise 的基础上.它不能与普通回调或者 node 回调一起用. Async/await 像 promise 一样,也是非阻塞的. Async/await 让

简单理解JavaScript 的async/await

什么是Async/Await? async 函数 : 是 Generator 函数的语法糖 async函数返回一个 Promise 对象,可以使用then方法添加回调函数.当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句. async/await与Promise一样,是非阻塞的 async函数返回的是 Promise 对象,可以作为await命令的参数 二.语法 1.返回 Promise 对象 async函数返回一个 Promise 对象. asyn

JavaScript 的 async/await

随着 Node 7 的发布,越来越多的人开始研究据说是异步编程终级解决方案的 async/await. 异步编程的最高境界,就是根本不用关心它是不是异步. async 函数就是隧道尽头的亮光,很多人认为它是异步操作的终极解决方案. async 和 await 起了什么作用 async 起什么作用 这个问题的关键在于,async 函数是怎么处理它的返回值的! 我们当然希望它能直接通过 return 语句返回我们想要的值,但是如果真是这样,似乎就没 await 什么事了.所以,写段代码来试试,看它到

ES6 Async/Await 完爆Promise的6个原因

自从Node的7.6版本,已经默认支持async/await特性了.如果你还没有使用过他,或者对他的用法不太了解,这篇文章会告诉你为什么这个特性"不容错过".本文辅以大量实例,相信你能很轻松的看懂,并了解Javascript处理异步的一大杀器. 文章灵感和内容借鉴了6 Reasons Why JavaScript's Async/Await Blows Promises Away (Tutorial),英文好的同学可以直接戳原版参考. 初识Async/await 对于还不了解Async

Async/Await替代Promise的6个理由

译者按: Node.js的异步编程方式有效提高了应用性能:然而回调地狱却让人望而生畏,Promise让我们告别回调函数,写出更优雅的异步代码:在实践过程中,却发现Promise并不完美:技术进步是无止境的,这时,我们有了Async/Await. 原文: 6 Reasons Why JavaScript’s Async/Await Blows Promises Away 译者: Fundebug 为了保证可读性,本文采用意译而非直译. Node.js 7.6已经支持async/await了,如果你

从地狱到天堂,Node 回调向 async/await 转变

Node7.6 开始正式支持 async/await,而 async/await 由于其可以以同步形式的代码书写异步程序,被喻为异步调用的天堂.然而 Node 的回调模式在已经根深蒂固,这个被喻为"回调地狱"的结构形式推动了 Promise 和 ES6 的迅速成型.然而,从地狱到天堂,并非一步之遥! async/await 基于 Promise,而不是基于回调,所以要想从回调地狱中解脱出来,首先要把回调实现修改为 Promise 实现--问题来了,Node 这么多库函数,还有更多的第三