1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 10:22:23 +00:00

docs(set): edit set

This commit is contained in:
ruanyf 2016-12-15 15:24:30 +08:00
parent ad472cdf6a
commit aab07bdbc8
3 changed files with 18 additions and 17 deletions

View File

@ -742,9 +742,9 @@ function* somethingAsync(x) {
### 含义
ES7提供了`async`函数,使得异步操作变得更加方便。`async`函数是什么?一句话,`async`函数就是Generator函数的语法糖。
ES2017 标准提供了`async`函数,使得异步操作变得更加方便。
前文有一个Generator函数依次读取两个文件。
`async`函数是什么?一句话,`async`函数就是 Generator 函数的语法糖。前文有一个 Generator 函数,依次读取两个文件。
```javascript
var fs = require('fs');
@ -777,25 +777,25 @@ var asyncReadFile = async function (){
};
```
一比较就会发现,`async`函数就是将Generator函数的星号`*`)替换成`async`,将`yield`替换成`await`,仅此而已。
一比较就会发现,`async`函数就是将 Generator 函数的星号(`*`)替换成`async`,将`yield`替换成`await`,仅此而已。
`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`命令的语法糖。
进一步说,`async`函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而`await`命令就是内部`then`命令的语法糖。
### 语法
@ -816,7 +816,7 @@ f().then(v => console.log(v))
上面代码中,函数`f`内部`return`命令返回的值,会被`then`方法回调函数接收到。
`async`函数内部抛出错误会导致返回的Promise对象变为`reject`状态。抛出的错误对象会被`catch`方法回调函数接收到。
`async`函数内部抛出错误,会导致返回的 Promise 对象变为`reject`状态。抛出的错误对象会被`catch`方法回调函数接收到。
```javascript
async function f() {
@ -830,7 +830,7 @@ f().then(
// Error: 出错了
```
2`async`函数返回的Promise对象必须等到内部所有`await`命令的Promise对象执行完才会发生状态改变。也就是说只有`async`函数内部的异步操作执行完,才会执行`then`方法指定的回调函数。
2`async`函数返回的 Promise 对象,必须等到内部所有`await`命令的Promise对象执行完才会发生状态改变,除非遇到`return`语句或者抛出错误。也就是说,只有`async`函数内部的异步操作执行完,才会执行`then`方法指定的回调函数。
下面是一个例子。
@ -844,7 +844,9 @@ getTitle('https://tc39.github.io/ecma262/').then(console.log)
// "ECMAScript 2017 Language Specification"
```
3正常情况下`await`命令后面是一个Promise对象。如果不是会被转成一个立即`resolve`的Promise对象。
上面代码中,函数`getTitle`内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行`then`方法里面的`console.log`
3正常情况下`await`命令后面是一个 Promise 对象。如果不是,会被转成一个立即`resolve`的 Promise 对象。
```javascript
async function f() {
@ -1008,8 +1010,6 @@ function spawn(genF) {
}
```
`async`函数是非常新的语法功能,新到都不属于 ES6而是属于 ES7。目前它仍处于提案阶段但是转码器`Babel``regenerator`都已经支持,转码后就能使用。
### async 函数的用法
`async`函数返回一个Promise对象可以使用`then`方法添加回调函数。当函数执行的时候,一旦遇到`await`就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
@ -1047,7 +1047,7 @@ async function asyncPrint(value, ms) {
asyncPrint('hello world', 50);
```
上面代码指定50毫秒以后输出"hello world"
上面代码指定50毫秒以后输出`hello world`
Async函数有多种使用形式。
@ -1323,7 +1323,7 @@ async function logInOrder(urls) {
## 异步遍历器
《遍历器》一章说过Iterator接口是一种数据遍历的协议只要调用遍历器对象的`next`方法,就会得到一个表示当前成员信息的对象`{value, done}`。其中,`value`表示当前的数据的值,`done`是一个布尔值,表示遍历是否结束。
《遍历器》一章说过Iterator 接口是一种数据遍历的协议,只要调用遍历器对象的`next`方法,就会得到一个表示当前成员信息的对象`{value, done}`。其中,`value`表示当前的数据的值,`done`是一个布尔值,表示遍历是否结束。
这隐含着规定,`next`方法是同步的,只要调用就必须立刻返回值。也就是说,一旦执行`next`方法,就必须同步地得到`value``done`这两方面的信息。这对于同步操作当然没有问题但对于异步操作就不太合适了。目前的解决方法是Generator函数里面的异步操作返回一个Thunk函数或者Promise对象`value`属性是一个Thunk函数或者Promise对象等待以后返回真正的值`done`属性则还是同步产生的。
@ -1587,3 +1587,4 @@ async function* gen2() {
// a
// b
```

View File

@ -166,7 +166,7 @@ Set结构的实例有四个遍历方法可以用于遍历成员。
**1`keys()``values()``entries()`**
`key`方法、`value`方法、`entries`方法返回的都是遍历器对象详见《Iterator对象》一章。由于Set结构没有键名只有键值或者说键名和键值是同一个值所以`key`方法和`value`方法的行为完全一致。
`keys`方法、`values`方法、`entries`方法返回的都是遍历器对象详见《Iterator 对象》一章)。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以`keys`方法和`values`方法的行为完全一致。
```javascript
let set = new Set(['red', 'green', 'blue']);

View File

@ -303,7 +303,7 @@ let obj = {
};
Reflect.ownKeys(obj)
// [Symbol(my_key), 'enum', 'nonEnum']
// ["enum", "nonEnum", Symbol(my_key)]
```
由于以 Symbol 值作为名称的属性,不会被常规方法遍历得到。我们可以利用这个特性,为对象定义一些非私有的、但又希望只用于内部的方法。