Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

通过一些例子深入了解 JavaScript 的 Async 和 Await #5832

Conversation

xionglong58
Copy link
Contributor

@xionglong58 xionglong58 commented May 22, 2019

译文翻译完成,resolve #5732

本文三人校对

@JaxNext
Copy link
Contributor

JaxNext commented May 22, 2019

认领校对。

@fanyijihua
Copy link
Collaborator

@baddyo 好的呢 🍺

@lebenito030
Copy link
Contributor

校对认领

@fanyijihua
Copy link
Collaborator

@Mcskiller 妥妥哒 🍻

Copy link
Contributor

@JaxNext JaxNext left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

校对完成。@leviding @xionglong58
翻译得很到位,译者对知识点得理解很透彻。
辛苦了。


![](https://cdn-images-1.medium.com/max/3840/1*3kAwfTZXxNynBOB5O6VQtg.jpeg)

In the beginning, there were callbacks. **A callback is nothing special but a function that is executed at some later time.** Due to JavScript’s asynchronous nature, a callback is required in many places, where the results are not available immediately.
首先来了解下回调函数。**回调函数会在被调用后的某一时刻执行,除此之外与其他普通函数并无差别。**由于 JS 的异步特征,在一些不能立即获得函数返回值的地方都需要使用回调函数。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【 首先来了解下回调函数。】=>【首先来了解一下回调函数。】

句首多个两个空格。


![](https://cdn-images-1.medium.com/max/3840/1*3kAwfTZXxNynBOB5O6VQtg.jpeg)

In the beginning, there were callbacks. **A callback is nothing special but a function that is executed at some later time.** Due to JavScript’s asynchronous nature, a callback is required in many places, where the results are not available immediately.
首先来了解下回调函数。**回调函数会在被调用后的某一时刻执行,除此之外与其他普通函数并无差别。**由于 JS 的异步特征,在一些不能立即获得函数返回值的地方都需要使用回调函数。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【由于 JS 的异步特征,】=>【由于 JavaScript 的异步特征,】


Here’s an example of reading a file in Node.js (asynchronously)
下面是一个 Node.js 读取文件时的示例(异步操作)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【读取文件时的示例】=>【读取文件的示例】


Here’s an example of reading a file in Node.js (asynchronously)
下面是一个 Node.js 读取文件时的示例(异步操作)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【—】=>【——】

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[下面是一个 Node.js 读取文件时的示例]=>[下面是一个使用 Node.js 读取文件时的示例]

@@ -21,65 +21,64 @@ fs.readFile(__filename, 'utf-8', (err, data) => {
console.log(data);
});
```
但当我们要处理多重异步操作时问题就会凸显出来。假设有下面的应用场景(其中的所有操作都是异步的)—
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【—】=>【——】

Note the `async` in the callback to the `.map`. We might expect that `counts` variable will contain the numbers of repos. However, as we have seen earlier, **all async functions return promises.** Hence, `counts` is actually **an array of promises.** `.map` calls the anonymous callback with every `username`, and a promise is returned with every invocation which `.map` keeps in the resulting array.

### Too sequential using await
注意 `async` 在 `.map`方法中。我们可能希望变量 `counts` 存储着的公开仓库数量。但是,就如我们之前所见,**所有的 async 函数均返回 promise 对象。** 因此,`counts` 实际上是一个**promise 对象数组。** `.map` 为每一个 `username` 调用异步函数,`.map` 方法将每次调用返回的 promise 结果保存在数组中。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【实际上是一个promise 对象数组。 】=>【实际上是一个 promise 对象数组。

“一个”后面应添加一个空格;
句末多了个空格。


We may also think of a solution such as
我们可能也会有其它解决方法,比如
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【比如 —】=>【比如 ——】

@@ -431,11 +427,11 @@ async function fetchAllCounts(users) {
}
```

We are manually fetching each count, and appending them in the `counts` array. The **problem with this code** is that until the first username’s count is fetched, **the next will not start.** At a time, **only one repo count** is fetched.
我们手动获取了每一个 count,并将它们 append 到 `counts` 数组中。**程序的问题在于**第一个用户的 count 被获取之后,第二个用户的 count 才能被获取。同一时间,只有一个**公开仓库数量**可以被获取。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【并将它们 append 到】=>【并将它们添加到】


If a single fetch takes 300 ms, then `fetchAllCounts` will take ~900ms for 3 users. As we can see that time usage will linearly grow with user counts. Since the **fetching of repo counts is not co-dependent**, we can **parallelize the operation.**
如果一个 fetch 操作耗时 300 ms,那么 `fetchAllCounts` 函数耗时大概在 900ms 左右。由此可见,程序耗时会随着用户数量的增加而线性增加。因为**获取不同用户公开仓库数量之间没有依赖**,我们可以将**操作并行处理。**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【大概在 900ms 左右。】=>【大概在 900 ms 左右。】

@@ -447,11 +443,11 @@ async function fetchAllCounts(users) {
}
```

`Promise.all` receives an array of promises as input and returns a promise as output. The returned promise resolves with **an array of all promise resolutions or rejects with the first rejection.** However, it may not be feasible to start all promises at the same time. Maybe you want to complete promises in batches. You can look at **[p-map](https://github.com/sindresorhus/p-map)** for limited concurrency.
`Promise.all` 接受一个 promise 对象数组作为输入,返回一个 promise 对象。当所有 promise 对象的状态都转变成 resolved 时,返回值为**所有 promise 对应返回值组成的 promise 数组**,只要有一个 promise 对象被 rejected,`Promise.all` 的返回值为**第一个被 rejected 的 promise 对象对应的返回值。**** 但是,同时运行所有 promise 的操作可能行不通。可能你想批量执行 promise。你可以考虑下使用 **[p-map](https://github.com/sindresorhus/p-map)** 实现受限的并发。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

第一个被 rejected 的 promise 对象对应的返回值。** 】=>【第一个被 rejected 的 promise 对象对应的返回值。

去掉句末的两个星号和一个空格。

Copy link
Contributor

@fireairforce fireairforce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

随便提了点意见


Here’s an example of reading a file in Node.js (asynchronously)
下面是一个 Node.js 读取文件时的示例(异步操作)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[下面是一个 Node.js 读取文件时的示例]=>[下面是一个使用 Node.js 读取文件时的示例]

@@ -21,65 +21,64 @@ fs.readFile(__filename, 'utf-8', (err, data) => {
console.log(data);
});
```
但当我们要处理多重异步操作时问题就会凸显出来。假设有下面的应用场景(其中的所有操作都是异步的)—
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这段话上面有个换行

* The code becomes harder to read as one has to move from left to right to understand.
* Error handling is complicated and often leads to bad code.
* 不得不从左至右去理解代码,使得代码变得更难以阅读。
* 处理错误变得更加复杂,并且容易引发错误代码。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[处理错误]=>[错误处理]


![Using Promises](https://cdn-images-1.medium.com/max/2000/1*RMxmAiwD-QFKspkHx_nKmA.png)

The flow has become a familiar **top-to-bottom** rather than **left-to-right** as in callbacks, which is a plus. However, Promises still suffer from some problems
回调流程变成熟悉的**自上而下**,而不是**从左至右**,这是一个优点。但是 promise 仍然有一些缺点
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[回调流程变成熟悉的自上而下,而不是从左至右,这是一个优点。]=>[回调流程由从左至右结构变成我们所熟悉的自上而下的结构,这是一个优点]


**Let’s assume that we have a `for` loop that prints 0 to 10 at random intervals (0 to n seconds). We need to modify it using promises to print sequentially 0 to 10. For example, if 0 takes 6 seconds to print and 1 takes two seconds to print, then 1 should wait for 0 to print and so on.**
**假设要在 for 循环中以任意时间间隔(0 到 n 秒)输出数字 0 到 10。我们将使用 promise 去顺序打印 0 到 10,比如打印 0 需要 6 秒,打印 1 要延迟 2 秒,而 1 需要 0 打印完成之后才能打印,其它数字打印过程也类似。**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[for]=>[for]

* **注意到 async 函数是基于 promise 的这一点很重要。**
* async/await 并不是完全全新的概念。
* async/await 可以被理解为基于 promise 实现异步方案的一种替代方案。
* 我们可以使用 async/await 来避免使用**链式调用 promise**。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[我们可以使用 async/await 来避免使用链式调用 promise。]=>[我们可以使用 async/await 来避免链式调用 promise。]

* async/await 并不是完全全新的概念。
* async/await 可以被理解为基于 promise 实现异步方案的一种替代方案。
* 我们可以使用 async/await 来避免使用**链式调用 promise**
* async/await 允许代码异步执行的同时**保持正常的**、同步式的**感觉**。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[保持正常的]=>[保持正常]


They consist of two main keywords- async and await. **`async` is used to make a function asynchronous.** It **unlocks** the use of `await` inside these functions. Using `await` in any other case is a syntax error.
async/await 包含两个关键字 async await**`async` 用来使得函数可以异步执行。`async` 使得在函数中可以使用 `await` 关键字,除此之外,在任何地方使用 `awiait` 都属于语法错误。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

async 用来使得函数可以异步执行。=> async 用来让函数可以异步执行。


They consist of two main keywords- async and await. **`async` is used to make a function asynchronous.** It **unlocks** the use of `await` inside these functions. Using `await` in any other case is a syntax error.
async/await 包含两个关键字 async await**`async` 用来使得函数可以异步执行。`async` 使得在函数中可以使用 `await` 关键字,除此之外,在任何地方使用 `awiait` 都属于语法错误。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[在任何地方使用 awiait 都属于语法错误] 这句话中await拼写错误

@@ -129,9 +128,9 @@ fn().then(console.log)
// hello
```

The function `fn` returns `'hello'`. Because we have used `async`, the return value `'hello'` is **wrapped in a promise** (via `Promise.resolve`).
函数 `fn` 返回值 `'hello'`,由于我们使用了 `async` 关键字,返回值 `'hello'` 是**一个新的 promise 对象**(通过 `Promise.resolve` 实现)。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

函数 fn 返回值 'hello' =》 函数 fn 返回值是 'hello'

@fireairforce
Copy link
Contributor

校对认领

@fireairforce
Copy link
Contributor

校对认领

哈哈哈,原来已经有两个人啦,算啦= = ,打扰啦,我看见这篇文章内容有意思就过来帮了点忙

@leviding
Copy link
Member

@fireairforce 可以的,算一个吧

感谢校对者,修改了很多格式问题
Copy link
Contributor

@lebenito030 lebenito030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

翻译得很不错,就是有一些格式需要调整一下(最后那个问题不知道是我这边的问题还是什么)
辛苦了_(:з)∠)_


* The code becomes harder to read as one has to move from left to right to understand.
* Error handling is complicated and often leads to bad code.
为了解决上述问题,JS 提出了 [**Promise**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。**现在,我们可以使用链式结构取代回调函数嵌套的结构。**下面是一个例子 ——
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『为了解决上述问题,JS 提出』=>『为了解决上述问题,JavaScript 提出』
上面都改了,和上面的保持一致吧


![Using Promises](https://cdn-images-1.medium.com/max/2000/1*RMxmAiwD-QFKspkHx_nKmA.png)
回调流程由**从左至右**结构变成我们所熟悉的**自上而下**的结构,这是一个优点,这是一个优点。但是 promise 仍然有一些缺点 ——
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『这是一个优点,这是一个优点。』=>『这是一个优点。』
这里好像重复了


### An async function always returns a promise.
### 一个 async 函数总是返回 promise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『一个 async 函数总是返回 promise』=>『一个 async 函数总是返回一个 promise 对象』
感觉这样翻合理些

fn().then(console.log);
```

Let’s examine the function `fn` line by line
让我们来逐行检验函数 `fn` —
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『让我们来逐行检验函数 fn —』=>『让我们来逐行检验函数 fn ——』


* `c` gets the value of `5` similarly and we delay for 1 second again using `await delayAndGetRandom(1000)`. We don’t use the resolved value in this case.
* 相似的,变量 `c` 值为 `5` ,然后使用 `await delayAndGetRandom(1000)` 又延时了 1 秒钟。在这个例子中我们并没有使用 `Promise.resolve` 返回值。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『相似的』=>『同样』

@@ -328,18 +326,17 @@ async function foo() {
}
```

Note that **we are returning** (and not awaiting) `canRejectOrReturn` from `foo` this time. `foo` will either **resolve with `'perfect number'`** or **reject with** Error('Sorry, number too big'). **The `catch` block will never be executed.**
注意这一次我们使用了 **return** (而不是 await)将函数`canRejectOrReturn` `foo` 函数中返回。`foo` 函数运行结果是 **resolved,返回值为`'perfect number'` **或者值为 Error('Sorry, number too big')。**`catch` 代码块永远都不会被执行。**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『将函数canRejectOrReturn』=>『将函数 canRejectOrReturn
英文和中文之间添加空格

@@ -314,9 +312,9 @@ async function foo() {
}
```

Since we are awaiting `canRejectOrReturn`, **its own rejection will be turned into a throw** and the `catch` block will execute. That is, `foo` will **either resolve with** `undefined` (because we are not returning anything in `try`) or **it will resolve with** `'error caught'`. It will never reject since we used a `try-catch` block to handle the error in the `foo` function itself.
因为我们在等待执行 `canRejectOrReturn` 函数的时候, **canRejectOrReturn 函数体内的 promise 会转移到 rejected 状态而抛出错误**,这将导致 `catch` 代码块被执行。也就是说 `foo` 函数运行结果为 `rejected`,返回值为 `undefined`(因为我们在 `try` 中没有返回值)或者 'error caught'`。因为我们在 `foo` 函数中使用了 `try-catch` 处理错误,所以说 `foo` 函数的结果永远不会是 rejected。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『或者 'error caught'』=>『或者 'error caught'。』
代码块的样式少了一个`,渲染出来是错的

@@ -328,18 +326,17 @@ async function foo() {
}
```

Note that **we are returning** (and not awaiting) `canRejectOrReturn` from `foo` this time. `foo` will either **resolve with `'perfect number'`** or **reject with** Error('Sorry, number too big'). **The `catch` block will never be executed.**
注意这一次我们使用了 **return** (而不是 await)将函数`canRejectOrReturn` `foo` 函数中返回。`foo` 函数运行结果是 **resolved,返回值为`'perfect number'` **或者值为 Error('Sorry, number too big')。**`catch` 代码块永远都不会被执行。**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『返回值为'perfect number'』=>『返回值为 'perfect number'
中英文之间添加空格

@@ -351,9 +348,9 @@ async function foo() {
}
```

In this case, `foo` **resolves with either** `'perfect number'` or **resolve with** `'error caught'`. **There is no rejection.** It is like the first example above with just `await`. Except, we **resolve with the value that** `canRejectOrReturn` produces rather than `undefined`.
在上面的例子中,`foo` 函数**运行结果为 resolved,**返回值为 'perfect number'` `'error caught'` **`foo` 函数的结果永远不会是 rejected。** 这就像上面那个只有 `await` 的例子。只是这里将函数 `canRejectOrReturn` 的 rejected 结果返回了,而不是返回了 `undefined`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『返回值为 'perfect number' 』=>『返回值为 'perfect number'
这里也少了一个 ` 符号,导致后面的样式渲染乱了

@@ -447,11 +442,11 @@ async function fetchAllCounts(users) {
}
```

`Promise.all` receives an array of promises as input and returns a promise as output. The returned promise resolves with **an array of all promise resolutions or rejects with the first rejection.** However, it may not be feasible to start all promises at the same time. Maybe you want to complete promises in batches. You can look at **[p-map](https://github.com/sindresorhus/p-map)** for limited concurrency.
`Promise.all` 接受一个 promise 对象数组作为输入,返回一个 promise 对象。当所有 promise 对象的状态都转变成 resolved 时,返回值为**所有 promise 对应返回值组成的 promise 数组**,只要有一个 promise 对象被 rejected,`Promise.all` 的返回值为**第一个被 rejected 的 promise 对象对应的返回值。**但是,同时运行所有 promise 的操作可能行不通。可能你想批量执行 promise。你可以考虑下使用 **[p-map](https://github.com/sindresorhus/p-map)** 实现受限的并发。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

『返回值为**第一个被 rejected 的 promise 对象对应的返回值。**但是』
这里不知道为什么没有渲染出来(用 view file 查看原文的时候是这个样子),不知道你们看是不是

@lebenito030
Copy link
Contributor

@leviding @xionglong58 校对完成

@leviding leviding added the enhancement 等待译者修改 label May 24, 2019
@leviding leviding added 标注 待管理员 Review and removed enhancement 等待译者修改 labels May 24, 2019

const obj = {
async getName() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

请问这个地方是误删了一行代码吗

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确认了一下,应该是误删


![](https://cdn-images-1.medium.com/max/3840/1*3kAwfTZXxNynBOB5O6VQtg.jpeg)

In the beginning, there were callbacks. **A callback is nothing special but a function that is executed at some later time.** Due to JavScript’s asynchronous nature, a callback is required in many places, where the results are not available immediately.
首先来了解下回调函数。**回调函数会在被调用后的某一时刻执行,除此之外与其他普通函数并无差别。**由于 JavaScript 的异步特征,在一些不能立即获得函数返回值的地方都需要使用回调函数。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
首先来了解下回调函数。**回调函数会在被调用后的某一时刻执行,除此之外与其他普通函数并无差别**由于 JavaScript 的异步特征,在一些不能立即获得函数返回值的地方都需要使用回调函数。
首先来了解下回调函数。**回调函数会在被调用后的某一时刻执行,除此之外与其他普通函数并无差别**由于 JavaScript 的异步特征,在一些不能立即获得函数返回值的地方都需要使用回调函数。


![Example of Callback hell.](https://cdn-images-1.medium.com/max/2000/1*uYstZyc0A4ZSO2Xxh-ASIg.png)
**注意回调函数的嵌套和程序末尾** `})` **的层级。** 鉴于结构上的相似性,这种方式被形象地称作[**回调地狱**](http://callbackhell.com/)或[**回调金字塔**](https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming))。这种方式的一些缺点是 ——
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
**注意回调函数的嵌套和程序末尾** `})` **的层级** 鉴于结构上的相似性,这种方式被形象地称作[**回调地狱**](http://callbackhell.com/)[**回调金字塔**](https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming))。这种方式的一些缺点是 ——
**注意回调函数的嵌套和程序末尾** `})` **的层级**鉴于结构上的相似性,这种方式被形象地称作[**回调地狱**](http://callbackhell.com/)[**回调金字塔**](https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming))。这种方式的一些缺点是 ——


* The code becomes harder to read as one has to move from left to right to understand.
* Error handling is complicated and often leads to bad code.
为了解决上述问题,JavaScript 提出了 [**Promise**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)。**现在,我们可以使用链式结构取代回调函数嵌套的结构。**下面是一个例子 ——
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
为了解决上述问题,JavaScript 提出了 [**Promise**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**现在,我们可以使用链式结构取代回调函数嵌套的结构。**下面是一个例子 ——
为了解决上述问题,JavaScript 提出了 [**Promise**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)**现在,我们可以使用链式结构取代回调函数嵌套的结构。**下面是一个例子 ——

### Syntax

They consist of two main keywords- async and await. **`async` is used to make a function asynchronous.** It **unlocks** the use of `await` inside these functions. Using `await` in any other case is a syntax error.
async/await 包含两个关键字 async 和 await。**`async` 用来使得函数可以异步执行。`async` 使得在函数中可以使用 `await` 关键字,除此之外,在任何地方使用 `await` 都属于语法错误。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async/await 包含两个关键字 async 和 await。**`async` 用来使得函数可以异步执行。`async` 使得在函数中可以使用 `await` 关键字,除此之外,在任何地方使用 `await` 都属于语法错误。
async/await 包含两个关键字 async 和 await。**`async` 用来使得函数可以异步执行**`async` 使得在函数中可以使用 `await` 关键字,除此之外,在任何地方使用 `await` 都属于语法错误。


If the return value is primitive, `Promise.resolve` returns a **promise-wrapped version of the value.** However, when the return value is a promise object, **the same object is returned without any wrapping.**
如果返回值是一个原始值,`Promise.resolve` 则返回该值的一个 **promise 版本**。 但是,如果返回值是 promise 对象,那么 `Promise.resolve` 将**原封不动地返回这个对象**。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
如果返回值是一个原始值,`Promise.resolve` 则返回该值的一个 **promise 版本** 但是,如果返回值是 promise 对象,那么 `Promise.resolve`**原封不动地返回这个对象**
如果返回值是一个原始值,`Promise.resolve` 则返回该值的一个 **promise 版本**。但是,如果返回值是 promise 对象,那么 `Promise.resolve`**原封不动地返回这个对象**

@@ -300,9 +297,9 @@ return 'perfect number';
}
```

`canRejectOrReturn()` is an async function and it will either **resolve with** `'perfect number'` or **reject with** Error('Sorry, number too big').
`canRejectOrReturn()` 是一个 async 函数,他可能返回`'perfect number'` 也可能抛出错误('Sorry, number too big')。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`canRejectOrReturn()` 是一个 async 函数,他可能返回`'perfect number'` 也可能抛出错误('Sorry, number too big')。
`canRejectOrReturn()` 是一个 async 函数,他可能返回 `'perfect number'` 也可能抛出错误('Sorry, number too big')。

@@ -314,9 +311,9 @@ async function foo() {
}
```

Since we are awaiting `canRejectOrReturn`, **its own rejection will be turned into a throw** and the `catch` block will execute. That is, `foo` will **either resolve with** `undefined` (because we are not returning anything in `try`) or **it will resolve with** `'error caught'`. It will never reject since we used a `try-catch` block to handle the error in the `foo` function itself.
因为我们在等待执行 `canRejectOrReturn` 函数的时候, **canRejectOrReturn 函数体内的 promise 会转移到 rejected 状态而抛出错误**,这将导致 `catch` 代码块被执行。也就是说 `foo` 函数运行结果为 `rejected`,返回值为 `undefined`(因为我们在 `try` 中没有返回值)或者 `'error caught'`。因为我们在 `foo` 函数中使用了 `try-catch` 处理错误,所以说 `foo` 函数的结果永远不会是 rejected。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
因为我们在等待执行 `canRejectOrReturn` 函数的时候, **canRejectOrReturn 函数体内的 promise 会转移到 rejected 状态而抛出错误**,这将导致 `catch` 代码块被执行。也就是说 `foo` 函数运行结果为 `rejected`,返回值为 `undefined`(因为我们在 `try` 中没有返回值)或者 `'error caught'`。因为我们在 `foo` 函数中使用了 `try-catch` 处理错误,所以说 `foo` 函数的结果永远不会是 rejected。
因为我们在等待执行 `canRejectOrReturn` 函数的时候**canRejectOrReturn 函数体内的 promise 会转移到 rejected 状态而抛出错误**,这将导致 `catch` 代码块被执行。也就是说 `foo` 函数运行结果为 `rejected`,返回值为 `undefined`(因为我们在 `try` 中没有返回值)或者 `'error caught'`。因为我们在 `foo` 函数中使用了 `try-catch` 处理错误,所以说 `foo` 函数的结果永远不会是 rejected。

@@ -351,9 +347,9 @@ async function foo() {
}
```

In this case, `foo` **resolves with either** `'perfect number'` or **resolve with** `'error caught'`. **There is no rejection.** It is like the first example above with just `await`. Except, we **resolve with the value that** `canRejectOrReturn` produces rather than `undefined`.
在上面的例子中,`foo` 函数**运行结果为 resolved,**返回值为 `'perfect number'` `'error caught'` **`foo` 函数的结果永远不会是 rejected。** 这就像上面那个只有 `await` 的例子。只是这里将函数 `canRejectOrReturn` 的 rejected 结果返回了,而不是返回了 `undefined`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
在上面的例子中,`foo` 函数**运行结果为 resolved**返回值为 `'perfect number'``'error caught'` **`foo` 函数的结果永远不会是 rejected。** 这就像上面那个只有 `await` 的例子。只是这里将函数 `canRejectOrReturn` 的 rejected 结果返回了,而不是返回了 `undefined`
在上面的例子中,`foo` 函数**运行结果为 resolved**返回值为 `'perfect number'``'error caught'`**`foo` 函数的结果永远不会是 rejected。** 这就像上面那个只有 `await` 的例子。只是这里将函数 `canRejectOrReturn` 的 rejected 结果返回了,而不是返回了 `undefined`


You can break return await canRejectOrReturn(); to see the effect
你可以将语句 return await canRejectOrReturn();拆开再看看效果 —
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
你可以将语句 return await canRejectOrReturn();拆开再看看效果 ——
你可以将语句 `return await canRejectOrReturn();` 拆开再看看效果 ——

@@ -412,12 +408,10 @@ const counts = users.map(async username => {
return count;
});
```
### 过于按顺序使用 await
注意 `async` 在 `.map`方法中。我们可能希望变量 `counts` 存储着的公开仓库数量。但是,就如我们之前所见,**所有的 async 函数均返回 promise 对象。** 因此,`counts` 实际上是一个 **promise 对象数组。**`.map` 为每一个 `username` 调用异步函数,`.map` 方法将每次调用返回的 promise 结果保存在数组中。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
注意 `async``.map`方法中。我们可能希望变量 `counts` 存储着的公开仓库数量。但是,就如我们之前所见,**所有的 async 函数均返回 promise 对象** 因此,`counts` 实际上是一个 **promise 对象数组**`.map` 为每一个 `username` 调用异步函数,`.map` 方法将每次调用返回的 promise 结果保存在数组中。
注意 `async``.map`方法中。我们可能希望变量 `counts` 存储着的公开仓库数量。但是,就如我们之前所见,**所有的 async 函数均返回 promise 对象**因此,`counts` 实际上是一个 **promise 对象数组**`.map` 为每一个 `username` 调用异步函数,`.map` 方法将每次调用返回的 promise 结果保存在数组中。

@leviding
Copy link
Member

@xionglong58

  1. 格式上还有些细节问题需要修改,我指出了一些,并不一定是所有,请自行检查修改原文,例如我只出了部分加粗格式错误,需要调整。

image

  1. 有一些校对意见没有修改,麻烦确认下是不需要改还是漏掉了。

@xionglong58
Copy link
Contributor Author

@fanyijihua 修改完成

@leviding leviding added 标注 待管理员 Review and removed enhancement 等待译者修改 labels May 27, 2019
@leviding leviding merged commit 60d87d2 into xitu:master May 27, 2019
@leviding
Copy link
Member

@xionglong58 已经 merge 啦~ 快快麻溜发布到掘金然后给我发下链接,方便及时添加积分哟。

文章发布时,标题前面那个大图,你可以在上传掘金的时候作为题图使用,然后在文中删除那个图就行啦。

掘金翻译计划有自己的知乎专栏,你也可以投稿哈,推荐使用一个好用的插件
专栏地址:https://zhuanlan.zhihu.com/juejinfanyi

@leviding leviding added 翻译完成 and removed 标注 待管理员 Review 正在校对 labels May 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

通过一些例子深入了解 JavaScript 的 Async 和 Await
6 participants