# Async/Await胜过Promise的6个理由（自译）

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.

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.

### Async/await基础

• async/await是一种书写异步代码的新方法，在这之前使用回调函数和promise来设置异步代码。
• async/await实际上是在promise的基础上构建的，他不能和纯回调函数(plain callbacks)和节点回调函数(node callbacks)一起使用。
• async/await很像promise，是非阻塞的。
• async/await让异步代码的外观和行为像同步代码。这就是他厉害的地方。

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

### 语法

And this is how it looks with async/await

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.

1. 我们的函数前面有一个关键字asyncawait关键字只能在async定义的函数内部使用，任何async函数返回一个隐式的promise，并且这个promise的resolve将会是这个函数中的return（在上例中是字符串"node"）。
2. 前面一点暗示了我们不能在代码的最外层使用await，因为那不再一个async函数内部。

3. await getJSON()意味着console.log()的调用会等到getJSON()resolve之后。

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.

### 为什么async/await更好？

#### 1. 简洁干净

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.parse fails 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.

#### 2. 异常处理

async/await 终于让使用同样的结构，好并且成熟的try/catch来处理同步和异步异常成为可能。在下面使用promise的例子中，当JSON.parse失败时，try/catch不会去处理异常，因为错误在promise内部产生，我们需要在promise上调用.catch并重复你异常处理的代码。这用法看起来会比在你的成品代码里使用console.log更加成熟。

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.

#### 3. 条件语句

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.

（上面的代码）只是看着就会头痛。很容易让人迷失在嵌套（6层），支架（？）和返回由主要promise来产生最终结果所需要的声明之中。

4.Intermediate values
You have probably found yourself in a situation where you call a promise1 and 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

#### 4. 中间值

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.

#### 5. 异常栈

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).

#### 6. Debugging

1. 你不能在一列返回表达式的函数上打断点。

1. 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.
2. 如果你在.then代码块内部打断点，并且用了bebug的快捷方式，比如step-over，debugger不会执行下一个.then因为他只能在同步代码中执行。
用async/await的话你不需要一列函数，并且你可以单步调试await来像普通同步代码一样调用。

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.

### 总结

async/await是近几年javascript新增的最具革命性的特性之一。它能让你实现与杂乱的promise等价的功能，同时提供了直接了当的替换方案。

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.

### 关注点

• 它会让异步代码更加不显眼：我们的眼睛习惯了当看到回调或者.then进而关注异步代码，这将会花费你几周来让你的眼睛适应新写法，但是C#许多年前就有这个特性，并且熟悉这种写法的人知道这种写法带来的好处远远值得去克服这些很小的麻烦。
• node7还不是LTS版本：是的，但是node8下个月（原文发布于2017年3月26日）就要出了。迁移你的代码库到新版本将很可能不需要花费太大力气。