mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 10:22:23 +00:00
edit async
This commit is contained in:
parent
f5d01f117d
commit
29e8701258
@ -697,7 +697,7 @@ function* somethingAsync(x) {
|
||||
|
||||
### 含义
|
||||
|
||||
ES7提供了`async`函数,使得异步操作变得更加方便。async 函数是什么?一句话,async函数就是Generator函数的语法糖。
|
||||
ES7提供了`async`函数,使得异步操作变得更加方便。`async`函数是什么?一句话,`async`函数就是Generator函数的语法糖。
|
||||
|
||||
前文有一个Generator函数,依次读取两个文件。
|
||||
|
||||
@ -732,23 +732,23 @@ var asyncReadFile = async function (){
|
||||
};
|
||||
```
|
||||
|
||||
一比较就会发现,async函数就是将Generator函数的星号(*)替换成async,将yield替换成await,仅此而已。
|
||||
一比较就会发现,`async`函数就是将Generator函数的星号(`*`)替换成`async`,将`yield`替换成`await`,仅此而已。
|
||||
|
||||
async 函数对 Generator 函数的改进,体现在以下三点。
|
||||
`async`函数对 Generator 函数的改进,体现在以下三点。
|
||||
|
||||
(1)内置执行器。Generator函数的执行必须靠执行器,所以才有了co模块,而async 函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。
|
||||
(1)内置执行器。Generator函数的执行必须靠执行器,所以才有了`co`模块,而`async`函数自带执行器。也就是说,`async`函数的执行,与普通函数一模一样,只要一行。
|
||||
|
||||
```javascript
|
||||
var result = asyncReadFile();
|
||||
```
|
||||
|
||||
上面的代码调用了`asyncReadFile`函数,然后它就会自动执行,输出最后结果。这完全不像Generator函数,需要调用`next`方法,或者用co模块,才能得到真正执行,得到最后结果。
|
||||
上面的代码调用了`asyncReadFile`函数,然后它就会自动执行,输出最后结果。这完全不像Generator函数,需要调用`next`方法,或者用`co`模块,才能得到真正执行,得到最后结果。
|
||||
|
||||
(2)更好的语义。`async`和`await`,比起星号和`yield`,语义更清楚了。`async`表示函数里有异步操作,`await`表示紧跟在后面的表达式需要等待结果。
|
||||
|
||||
(3)更广的适用性。 co模块约定,`yield`命令后面只能是Thunk函数或Promise对象,而`async`函数的`await`命令后面,可以是Promise对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。
|
||||
(3)更广的适用性。 `co`模块约定,`yield`命令后面只能是Thunk函数或Promise对象,而`async`函数的`await`命令后面,可以是Promise对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。
|
||||
|
||||
(4)返回值是Promise。async函数的返回值是Promise对象,这比Generator函数的返回值是Iterator对象方便多了。你可以用`then`方法指定下一步的操作。
|
||||
(4)返回值是Promise。`async`函数的返回值是Promise对象,这比Generator函数的返回值是Iterator对象方便多了。你可以用`then`方法指定下一步的操作。
|
||||
|
||||
进一步说,async函数完全可以看作多个异步操作,包装成的一个Promise对象,而`await`命令就是内部`then`命令的语法糖。
|
||||
|
||||
@ -841,7 +841,7 @@ asyncPrint('hello world', 50);
|
||||
|
||||
### 注意点
|
||||
|
||||
await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。
|
||||
第一点,`await`命令后面的Promise对象,运行结果可能是rejected,所以最好把`await`命令放在`try...catch`代码块中。
|
||||
|
||||
```javascript
|
||||
async function myFunction() {
|
||||
@ -861,7 +861,29 @@ async function myFunction() {
|
||||
}
|
||||
```
|
||||
|
||||
await命令只能用在async函数之中,如果用在普通函数,就会报错。
|
||||
第二点,多个`await`命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
|
||||
|
||||
```javascript
|
||||
let foo = await getFoo();
|
||||
let bar = await getBar();
|
||||
```
|
||||
|
||||
上面代码中,`getFoo`和`getBar`是两个独立的异步操作(即互不依赖),被写成继发关系。这样比较耗时,因为只有`getFoo`完成以后,才会执行`getBar`,完全可以让它们同时触发。
|
||||
|
||||
```javascript
|
||||
// 写法一
|
||||
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
|
||||
|
||||
// 写法二
|
||||
let fooPromise = getFoo();
|
||||
let barPromise = getBar();
|
||||
let foo = await fooPromise;
|
||||
let bar = await barPromise;
|
||||
```
|
||||
|
||||
上面两种写法,`getFoo`和`getBar`都是同时触发,这样就会缩短程序的执行时间。
|
||||
|
||||
第三点,`await`命令只能用在`async`函数之中,如果用在普通函数,就会报错。
|
||||
|
||||
```javascript
|
||||
async function dbFuc(db) {
|
||||
@ -874,7 +896,7 @@ async function dbFuc(db) {
|
||||
}
|
||||
```
|
||||
|
||||
上面代码会报错,因为await用在普通函数之中了。但是,如果将forEach方法的参数改成async函数,也有问题。
|
||||
上面代码会报错,因为await用在普通函数之中了。但是,如果将`forEach`方法的参数改成`async`函数,也有问题。
|
||||
|
||||
```javascript
|
||||
async function dbFuc(db) {
|
||||
@ -887,7 +909,7 @@ async function dbFuc(db) {
|
||||
}
|
||||
```
|
||||
|
||||
上面代码可能不会正常工作,原因是这时三个`db.post`操作将是并发执行,也就是同时执行,而不是继发执行。正确的写法是采用for循环。
|
||||
上面代码可能不会正常工作,原因是这时三个`db.post`操作将是并发执行,也就是同时执行,而不是继发执行。正确的写法是采用`for`循环。
|
||||
|
||||
```javascript
|
||||
async function dbFuc(db) {
|
||||
@ -899,7 +921,7 @@ async function dbFuc(db) {
|
||||
}
|
||||
```
|
||||
|
||||
如果确实希望多个请求并发执行,可以使用 Promise.all 方法。
|
||||
如果确实希望多个请求并发执行,可以使用`Promise.all`方法。
|
||||
|
||||
```javascript
|
||||
async function dbFuc(db) {
|
||||
@ -924,7 +946,7 @@ async function dbFuc(db) {
|
||||
}
|
||||
```
|
||||
|
||||
ES6将await增加为保留字。使用这个词作为标识符,在ES5是合法的,在ES6将抛出SyntaxError。
|
||||
ES6将`await`增加为保留字。使用这个词作为标识符,在ES5是合法的,在ES6将抛出SyntaxError。
|
||||
|
||||
### 与Promise、Generator的比较
|
||||
|
||||
|
@ -161,6 +161,7 @@
|
||||
- Jafar Husain, [Asynchronous Generators for ES7](https://github.com/jhusain/asyncgenerator): Async函数的深入讨论
|
||||
- Nolan Lawson, [Taming the asynchronous beast with ES7](http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html): async函数通俗的实例讲解
|
||||
- Jafar Husain, [Async Generators](https://docs.google.com/file/d/0B4PVbLpUIdzoMDR5dWstRllXblU/view?sle=true): 对async与Generator混合使用的一些讨论
|
||||
- Daniel Brain, [Understand promises before you start using async/await](https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8): 讨论async/await与Promise的关系
|
||||
|
||||
## Class
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user