记笔记,主要是为了提高学习效率,避免只看不动手,领略不到书的精髓,忽略到书中的重点知识,本文学习主要是根据阮一峰大神走的,很感谢阮一峰大神的无私奉献。如果想要了解更详细的关于本节的内容可以看阮一峰大神的ES6官网http://es6.ruanyifeng.com/#docs/generator
嗯、今天主要学的是Generator函数返回的遍历器对象的方法:throw()、return()
Generator函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后再Generator函数体内捕获。
throw方法可以接收一个参数,该参数会被catch语句接收,建议抛出Error对象的实例
var g = function *(){
try{
yield "welcome zhengzhou";
}catch(e){
console.log("内部捕获",e);//内部捕获 leo
}
}
var p = g();
console.log(p.next());//{ value: "welcome zhengzhou", done: false }
try{
p.throw('leo');
p.throw('donna');
}catch(e){
console.log("外部捕获",e);//外部捕获 donna
}
上面代码中,遍历器对象p连续抛出两个错误。第一个错误被Generator函数体内的catch语句捕获。p第二次抛出错误,由于Generator函数体内部的catch语句已经执行过了,不会再捕获到这个错误了,所以这个错误就被抛出了Generator函数体外,被函数体外的catch语句捕获
再看个
var g = function *(){
try{
yield "welcome zhengzhou";
}catch(e){
console.log("内部捕获",e);
}
}
var p = g();
console.log(p.next());//{ value: "welcome zhengzhou", done: false }
console.log(p.next());//{ value: undefined, done: true }
console.log(p.next());//{ value: undefined, done: true }
try{
p.throw('leo');
p.throw('donna');
}catch(e){
console.log("外部捕获",e);//外部捕获 leo
}
因为上面的Generator函数的遍历器对象调用了3次next方法,所以,当执行throw方法的时候,Generator函数对象已经遍历完成,所以,相当于Generator函数内部没有部署try…catch代码块,那么throw方法抛出的错误将被外部try…catch代码块捕获。函数体外的catch语句块,捕获了抛出的“leo”错误以后,就不会再继续try代码块里面剩余的语句了。
注意:如果Generator函数内部和外部都没有部署try…catch语句,那么程序将报错,直接中断执行。
throw方法被捕获以后,会附带执行下一条yield表达式,也就是说,会附带执行一次next方法。
var g = function *(){
try{
yield "welcome zhengzhou";
}catch(e){
console.log("内部捕获",e);
yield "gygq";
}
}
var p = g();
console.log(p.next());
try{
console.log(p.throw('leo'));
p.throw('donna');
}catch(e){
console.log("外部捕获",e);
}
//Object { value: "welcome zhengzhou", done: false }
//内部捕获 leo
// { value: "gygq", done: false }
//外部捕获 donna
从上面的打印结果,可以看出,throw方法抛出以后,它下面的yield表达式也被执行了
var g = function *(){
try{
yield "welcome zhengzhou";
}catch(e){
console.log("内部捕获",e);
yield "gygq";
}
yield "hello";
}
var p = g();
console.log(p.next());
try{
console.log(p.throw('leo'));
}catch(e){
console.log("外部捕获",e);
}
console.log(p.next());
//Object { value: "welcome zhengzhou", done: false }
//内部捕获 leo
// { value: "gygq", done: false }
//{ value: hello, done: false }
从上面的打印结果可以看出,,只要Generator函数内部部署了try…catch代码块,那么遍历器的throw方法抛出的错误,不影响下一次的遍历。
var g = function *(){
try{
yield "welcome zhengzhou";
}catch(e){
console.log("内部捕获",e);
yield "gygq";
}
yield "hello";
}
var p = g();
console.log(p.next());
try{
console.log(p.throw('leo'));
p.throw('donna');
}catch(e){
console.log("外部捕获",e);
}
console.log(p.next());
//Object { value: "welcome zhengzhou", done: false }
//内部捕获 leo
// { value: "gygq", done: false }
//外部捕获 donna
//{ value: undefined, done: true }
从上面的结果中我们发现,当我们抛出的错误被Generator函数体外的try…catch捕获以后,又去执行p.next()方法,value属性的值为undefined,done属性的结果为true,而Generator函数体内还有yield表达式没有执行完。这是因为一旦Generator执行过程中抛出错误,且没有被内部捕获,就不会再执行下去了。如果此后还有next方法将返回一个value属性等于undefined,done属性为true的对象,即JavaScript引擎认为这个Generator已经运行结束了。
return方法:
Generator函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且最终遍历Generator函数。
var g = function *(){
yield "leo";
yield "donna";
yield "hello";
}
var p = g();
console.log(p.next());
console.log(p.return("hello"));
console.log(p.next());
//Object { value: "leo", done: false }
//{ value: hello, done: true }
//{ value: undefined, done: true }
上面的代码中,遍历器对象p调用了return方法后,返回值的value属性就是return方法的参数hello,并且,Generator函数的遍历就中止了,返回值的done属性为true,以后再调用next方法,done属性总是返回true。
如果return方法调用是,不提供参数,则返回值的value属性为undefined。
如果Generator函数内部有try…finally代码块,那么return方法会推迟finally代码块执行完再执行
var g = function *(){
yield "leo";
try{
yield "donna";
}finally{
yield "hello";
}
yield "lalalal";
}
var p = g();
console.log(p.next());
console.log(p.next());
console.log(p.return("world"));
console.log(p.next());
console.log(p.next());
//Object { value: "leo", done: false }
//{ value: donna, done: false }
//{ value: hello, done: false }
//{ value: hello, world: true }
//{ value: undefined, done: true }
上面代码中,调用return方法后,就开始执行finally代码块,然后等到finally代码块执行完,再执行return方法。
再看一段代码
var g = function *(){
yield "leo";
try{
yield "donna";
}finally{
yield "hello";
}
yield "lalalal";
}
var p = g();
console.log(p.next());
console.log(p.return());
console.log(p.next());
console.log(p.next());
//Object { value: "leo", done: false }
//{ value: undefined, done: true }
//{ value: undefined, done: true }
//{ value: undefined, done: true }
我们发现上面代码,在还没有开始执行try…finally代码块的时候就调用了return方法,那么此时是不会等到finally代码块执行完Generator函数的遍历就中止了。所以,只有当调用return方法的时候,Generator函数正在执行try…finally的时候,return方法会等到finally代码块执行完执行,否则都是直接执行。