ES6之Generator(2)知识点总结(九)

记笔记,主要是为了提高学习效率,避免只看不动手,领略不到书的精髓,忽略到书中的重点知识,本文学习主要是根据阮一峰大神走的,很感谢阮一峰大神的无私奉献。如果想要了解更详细的关于本节的内容可以看阮一峰大神的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代码块执行完执行,否则都是直接执行。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值