diff --git a/docs/async.md b/docs/async.md index 5e3ee78..1038dcb 100644 --- a/docs/async.md +++ b/docs/async.md @@ -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的比较 diff --git a/docs/reference.md b/docs/reference.md index 468ff44..28d417a 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -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