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

docs(generator): edit generator.throw()

This commit is contained in:
ruanyf 2016-07-24 11:11:25 +08:00
parent aa7f34527b
commit e18aa221da
3 changed files with 68 additions and 15 deletions

View File

@ -414,7 +414,25 @@ ft(1, 2)(print);
你可能会问, Thunk函数有什么用回答是以前确实没什么用但是ES6有了Generator函数Thunk函数现在可以用于Generator函数的自动流程管理。
以读取文件为例。下面的Generator函数封装了两个异步操作。
Generator函数可以自动执行。
```javascript
function* gen() {
// ...
}
var g = gen();
var res = g.next();
while(!res.done){
console.log(res.value);
res = g.next();
}
```
上面代码中Generator函数`gen`会自动执行完所有步骤。
但是这不适合异步操作。如果必须保证前一步执行完才能执行后一步上面的自动执行就不可行。这时Thunk函数就能派上用处。以读取文件为例。下面的Generator函数封装了两个异步操作。
```javascript
var fs = require('fs');

View File

@ -443,6 +443,23 @@ try {
上面代码中,遍历器对象`i`连续抛出两个错误。第一个错误被Generator函数体内的`catch`语句捕获。`i`第二次抛出错误由于Generator函数内部的`catch`语句已经执行过了不会再捕捉到这个错误了所以这个错误就被抛出了Generator函数体被函数体外的`catch`语句捕获。
`throw`方法可以接受一个参数,该参数会被`catch`语句接收,建议抛出`Error`对象的实例。
```javascript
var g = function* () {
try {
yield;
} catch (e) {
console.log(e);
}
};
var i = g();
i.next();
i.throw(new Error('出错了!'));
// Error: 出错了!(…)
```
注意,不要混淆遍历器对象的`throw`方法和全局的`throw`命令。上面代码的错误,是用遍历器对象的`throw`方法抛出的,而不是用`throw`命令抛出的。后者只能被函数体外的`catch`语句捕获。
```javascript
@ -493,29 +510,47 @@ try {
// 外部捕获 a
```
上面代码中,遍历器函数`g`内部没有部署`try...catch`代码块,所以抛出的错误直接被外部`catch`代码块捕获。
上面代码中,Generator函数`g`内部没有部署`try...catch`代码块,所以抛出的错误直接被外部`catch`代码块捕获。
如果Generator函数内部部署了`try...catch`代码块,那么遍历器的`throw`方法抛出的错误,不影响下一次遍历,否则遍历直接终止
如果Generator函数内部和外部,都没有部署`try...catch`代码块,那么程序将报错,直接中断执行
```javascript
var gen = function* gen(){
try {
yield console.log('hello');
} catch (e) {
// ...
}
yield console.log('hello');
yield console.log('world');
}
var g = gen();
g.next();
g.throw();
g.next();
// hello
// world
// Uncaught undefined
```
上面代码在两次`next`方法之间,使用`throw`方法抛出了一个错误。由于这个错误在Generator函数内部被捕获了所以不影响第二次`next`方法的执行。
上面代码中,`g.throw`抛出错误以后,没有任何`try...catch`代码块可以捕获这个错误,导致程序报错,中断执行。
`throw`方法被捕获以后,会附带执行下一条`yield`语句。也就是说,会附带执行一次`next`方法。
```javascript
var gen = function* gen(){
try {
yield console.log('a');
} catch (e) {
// ...
}
yield console.log('b');
yield console.log('c');
}
var g = gen();
g.next() // a
g.throw() // b
g.next() // c
```
上面代码中,`g.throw`方法被捕获以后,自动执行了一次`next`方法,所以会打印`b`。另外也可以看到只要Generator函数内部部署了`try...catch`代码块,那么遍历器的`throw`方法抛出的错误,不影响下一次遍历。
另外,`throw`命令与`g.throw`方法是无关的,两者互不影响。
```javascript
var gen = function* gen(){
@ -535,9 +570,9 @@ try {
// world
```
上面代码中,`throw`命令抛出的错误不会影响到遍历器的状态,所以两次执行`next`方法,都取到了正确的操作。
上面代码中,`throw`命令抛出的错误不会影响到遍历器的状态,所以两次执行`next`方法,都进行了正确的操作。
这种函数体内捕获错误的机制,大大方便了对错误的处理。如果使用回调函数的写法,想要捕获多个错误,就不得不为每个函数内部写一个错误处理语句。现在可以只在Generator函数内部写一次`catch`语句。
这种函数体内捕获错误的机制,大大方便了对错误的处理。多个`yield`语句,可以只用一个`try...catch`代码块来捕获错误。如果使用回调函数的写法,想要捕获多个错误,就不得不为每个函数内部写一个错误处理语句,现在只在Generator函数内部写一次`catch`语句就可以了
Generator函数体外抛出的错误可以在函数体内捕获反过来Generator函数体内抛出的错误也可以被函数体外的`catch`捕获。
@ -561,7 +596,7 @@ try {
上面代码中,第二个`next`方法向函数体内传入一个参数42数值是没有`toUpperCase`方法的所以会抛出一个TypeError错误被函数体外的`catch`捕获。
一旦Generator执行过程中抛出错误就不会再执行下去了。如果此后还调用next方法将返回一个`value`属性等于`undefined``done`属性等于`true`的对象即JavaScript引擎认为这个Generator已经运行结束了。
一旦Generator执行过程中抛出错误且没有被内部捕获,就不会再执行下去了。如果此后还调用`next`方法,将返回一个`value`属性等于`undefined``done`属性等于`true`的对象即JavaScript引擎认为这个Generator已经运行结束了。
```javascript
function* g() {

View File

@ -95,7 +95,7 @@ $ node --v8-options | grep harmony
上面命令的输出结果,会因为版本的不同而有所不同。
我写了一个[ES-Checker](https://github.com/ruanyf/es-checker)模块用来检查各种运行环境对ES6的支持情况。访问[ruanyf.github.io/es-checker](http://ruanyf.github.io/es-checker)可以看到您的浏览器支持ES6的程度。运行下面的命令可以查看本机支持ES6的程度。
我写了一个[ES-Checker](https://github.com/ruanyf/es-checker)模块用来检查各种运行环境对ES6的支持情况。访问[ruanyf.github.io/es-checker](http://ruanyf.github.io/es-checker)可以看到您的浏览器支持ES6的程度。运行下面的命令可以查看你正在使用的Node环境对ES6的支持程度。
```bash
$ npm install -g es-checker