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);//这里捕获
}

Generator函数(二)的更多相关文章

  1. ES6 - Note7:Generator函数

    Generator函数 1.Generator函数是ES6增加的异步编程解决方案之一,与普通的函数行为完全不同,类似于一个状态机,内部封装了多个状态. 在函数定义的形式上,跟普通函数差不多,有两处不同 ...

  2. Generator函数语法解析

    转载请注明出处: Generator函数语法解析 Generator函数是ES6提供的一种异步编程解决方案,语法与传统函数完全不同.以下会介绍一下Generator函数. 写下这篇文章的目的其实很简单 ...

  3. ECMAScript 6 入门 ----Generator 函数

    本文转自:阮一峰老师的ECMAScript 6 入门,有时间可以看下评论! Generator 函数 简介 基本概念 Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不 ...

  4. 一次搞懂 Generator 函数

    1.什么是 Generator 函数 在Javascript中,一个函数一旦开始执行,就会运行到最后或遇到return时结束,运行期间不会有其它代码能够打断它,也不能从外部再传入值到函数体内 而Gen ...

  5. 前端笔记之ES678&Webpack&Babel(下)AMD|CMD规范&模块&webpack&Promise对象&Generator函数

    一.AMD和CMD规范(了解) 1.1传统的前端开发多个js文件的关系 yuan.js中定义了一个函数 function mianji(r){ return 3.14 * r * r } main.j ...

  6. JavaScript中的Generator函数

    1. 简介 Generator函数时ES6提供的一种异步编程解决方案.Generator语法行为和普通函数完全不同,我们可以把Generator理解为一个包含了多个内部状态的状态机. 执行Genera ...

  7. js-ES6学习笔记-Generator函数

    1.Generator 函数是 ES6 提供的一种异步编程解决方案.形式上,Generator 函数是一个普通函数,但是有两个特征.一是,function关键字与函数名之间有一个星号:二是,函数体内部 ...

  8. Generator函数执行器-co函数库源码解析

    一.co函数是什么 co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行.短小精悍只有短短200余行,就可以免去手动编写G ...

  9. 15.Generator 函数的语法

    Generator 函数的语法 Generator 函数的语法 简介 基本概念 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.本章详细介绍 Generat ...

随机推荐

  1. axios使用

    axios 基于promise用于浏览器和node.js的http客户端 特点 支持浏览器和node.js 支持promise 能拦截请求和响应 能转换请求和响应数据 能取消请求 自动转换JSON数据 ...

  2. [How to]使用自定义cell进行tableview的创建,适用于cell样式不发生变化的情况。

    1.简介 在tableview中又默认的cell格式,其中组织如下: <截取自官网文档> 最终的在页面上默认的cell也只能像上述那样的显示效果,如果这种要是无法满足我们的界面要求,那么我 ...

  3. mac date命令

    usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd ...

  4. 3.22. grep sed re

    1.整理正则表达式博客 re  http://www.cnblogs.com/oyoui/p/6599846.html 2.grep(正则表达式及字符处理) 1.显示出所有含有root的行: [roo ...

  5. java虚拟机字节码执行引擎

    定义 java虚拟机字节码执行引擎是jvm最核心的组成部分之一,它做的事情很简单:输入的是字节码文件,处理过程是字节码解析的等效过程,输出的是执行结果.在不同的虚拟机实现里,执行引擎在执行java代码 ...

  6. HDU-5351

    MZL's Border Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  7. git clone命令

    从远程clone一个仓库 ...知识浅薄 git clone都发现貌似用的不顺 因为我有几个git账号 但是我也不知道就是git账号是怎么保存在终端上的 所以当我需要用一个新的github账号来clo ...

  8. Django 定制验证码

    一.图片验证码 方式一: def get_validCode_img(request): path=os.path.join(settings.BASE_DIR,'static','image','1 ...

  9. ofbiz 之minilang解析

    编写一个simple method 首先我们需要对输入参数进行验证 ,判断参数是否完整. 1. 验证 1.1. Login-required :这是一个simple-method的属性,对是否需要登陆 ...

  10. webpy 访问静态文件

    1.在项目的根目录创建static文件夹 能够直接在网页中访问static文件夹中的文件 如果static文件夹有一个文件为favicon.ico,那么访问的地址为127.0.0.1:8080/sta ...