for...of循环

1.for...of循环可以自动遍历Generator函数,不需要再调用next方法

function* helloWorldGenerator(){
yield 'hello';
yield 'world';
return 'ending';
}
for (let f of helloWorldGenerator()){
console.log(f);//'hello','world'
} var hw = helloWorldGenerator();
hw.next();
hw.next();//done的值是false
hw.next();//done的值是true,所以此时不会再输出ending

这里使用for...of循环和next()方法遍历Generator函数,在使用for...of循环可以自动遍历Generator函数,且此时不再需要调用next方法。

而且遍历出来的结果也不同。

2.前面章节介绍过,for...of循环,扩展运算符(...),解构赋值和array.from方法内部调用的都是遍历器接口。这就是说,他们可以将Generator函数返回的Iterator对象作为参数。

function* numbers(){
yield 1;
yield 2;
return 3;
yield 4;
} [...numbers()];//[1,2],扩展运算符(...)
Array.from(numbers()) //[1,2],Array.from方法
let [x,y] = numbers(); //解构赋值
x//1
y//2 for(let n of numbers()){
console.log(n);
}
//1
//2

3.使用Generator函数和for...of循环为原生的JavaScript对象加上遍历接口

function* objectEntries(obj){
let propKeys = Reflect.ownKeys(obj);//获取一个对象obj的key
for(let propKey of propKeys){
yield [propKey,obj[propKey]];
}
}
let jane = {first:'jane',last:'Doe'};
for(let [key,value] of objectEntries(jane)){
console.log(`${key}:${value]`);
}
// first:jane
// last:Doe

第二种方法实现添加遍历接口

    function* objectEntries(obj){
let propKeys = Reflect.ownKeys(obj);
for(let propkey of propKeys){
yield [propkey,obj[propkey]];
}
}
let jane = {first:'jane',last:'doe'};
jane[System.iterator] = objectEntries;
for(let [key,value] of jane){
console.log(`${key}:${value}`);
}
// first:jane
// last:doe

Generator.prototype.throw()

1.Generator函数返回的遍历器都有一个throw方法,可以在函数体外抛出错误,在函数体内捕获错误。

var g = function* (){
while (true ){
try{
yield;
}catch (e){
if(e != 'a') throw e;
console.log('内部捕获',e);
}
}
};
var i = g();
i.next(); try{
i.throw('a');
i.throw('b');
}catch(e){
console.log('外部捕获',e);
}
//内部捕获 a
//外部捕获 b

总结一下,有几种错误抛出和捕获的情况。

(1)Generator函数体内有try...catch块,函数体外也有try...catch块,如果函数体外用多个throw方法抛出错误:

解决错误的情况:第一个throw方法,将被函数体内的捕获,后面的throw方法会被函数体外的捕获。(因为Generator函数内部的catch语句已经执行过了,不会再捕获到后面的throw方法抛出的错误)

(2)Generator函数体内和体外都有try...catch块,如果函数体外用throw命令抛出错误:

解决情况:因为用throw命令抛出的错误,只能被函数体外的catch捕获,即使函数体内有catch块。

(3)Generator函数体内没有try...catch块,函数体外有try...catch块,如果函数体外用throw方法或者throw命令抛出错误:

解决情况:被外部的try...catch块捕获。

(4)Generator函数体内和体外都没有try...catch块,那么如果抛出错误:程序会报错,直接中断执行。

2.关于Generator函数体内有无try...catch块,会不会影响到遍历器的状态,即关系到next方法会不会被正常执行。

如果Generator函数体内没有try...catch块,则遍历器的throw方法抛出的错误不会影响到下一次的遍历,否则遍历直接终止,但是如果用的是throw命令,则不会影响到遍历器的状态。

var gen = function* gen(){
yield console.log('hello');
yield console.log('world');
} var g = gen();
g.next();
try {
g.throw();
}catch(e){
g.next();
}
//hello

虽然Generator函数内部没有部署try...catch块,那么throw方法抛出的错误即使会被外部的try...catch代码块捕获。

但是第二次调用next()方法的时候遍历器状态已经变成终止了。但是使用throw命令(throw new Error())抛出的错误就不会影响到遍历器的状态,即next()方法。

3.Generator函数这种函数体内捕获错误的机制大大方便了对错误的处理。如果使用回调函数,想要捕获多个错误的话,就不得不为每个函数写一个错误处理语句。

但是使用Generator函数就会简化很多,例如

    function* g(){
try{
var a = yield foo('a');
var b = yield foo('b');
var c = yield foo('c');
}catch (e){
console.log(e);
}
console.log(a,b,c);
}

4.Generator函数体内抛出的错误也可以被函数体外的catch捕获。

    function* foo(){
var x = yield 3;
var y = x.toUpperCase();//这里报错
yield y;
}
var it = foo();
it.next(); try{
it.next(42);
}catch(err){
console.log(err);//这里捕获
}

最新文章

  1. Web Deploy自动配置
  2. MFC学习-第一课 MFC运行机制
  3. 优化后的二次测试Miller_Rabin素性测试算法
  4. 我装GitHub的过程
  5. 程序员的sql金典
  6. 关于FastDFS Java客户端源码中的一个不太明白的地方
  7. ajax-Ajax试题
  8. VS2015 新Web项目(C#6)出现CS1617异常的解决
  9. 全国计算机等级考试二级教程-C语言程序设计_第9章_数组
  10. Finance
  11. python基本数据类型——set
  12. python中sort命令介绍以及list结构中统计各元素出现的个数的方法
  13. Mastering MariaDB 神秘的MariaDB 中文翻译版
  14. 正则表达式中test,match,exec区别
  15. 监听软件异常崩溃并且保持日志--CrashHandler编写自己的异常捕获类
  16. MySQL性能测试工具sysbench的安装和使用
  17. Configure Virtual Serial Port Driver (vspd)注册表
  18. 目标检测之2015iccv---objdetection 专题论文
  19. DevExpress.XtraReports:XRPivotGrid 笔记
  20. Java JNI初探

热门文章

  1. Django 1.10中文文档-第一个应用Part3-视图和模板
  2. python基础===两个list之间移动元素
  3. python基础===利用PyCharm进行Python远程调试(转)
  4. 5-3 Linux内核计时、延时函数与内核定时器【转】
  5. nginx源码分析--使用GDB调试(strace、 pstack )
  6. 阿里云ECS的使用
  7. 关于IE8版本提示“不支持‘trim’此属性或者方法”的解决办法。转摘雨网络
  8. Leetcode 之Binary Tree Postorder Traversal(44)
  9. socket编程之select(),poll(),epoll()
  10. session和cookie基本操作