Generator函数(二)
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函数(二)的更多相关文章
- ES6 - Note7:Generator函数
Generator函数 1.Generator函数是ES6增加的异步编程解决方案之一,与普通的函数行为完全不同,类似于一个状态机,内部封装了多个状态. 在函数定义的形式上,跟普通函数差不多,有两处不同 ...
- Generator函数语法解析
转载请注明出处: Generator函数语法解析 Generator函数是ES6提供的一种异步编程解决方案,语法与传统函数完全不同.以下会介绍一下Generator函数. 写下这篇文章的目的其实很简单 ...
- ECMAScript 6 入门 ----Generator 函数
本文转自:阮一峰老师的ECMAScript 6 入门,有时间可以看下评论! Generator 函数 简介 基本概念 Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不 ...
- 一次搞懂 Generator 函数
1.什么是 Generator 函数 在Javascript中,一个函数一旦开始执行,就会运行到最后或遇到return时结束,运行期间不会有其它代码能够打断它,也不能从外部再传入值到函数体内 而Gen ...
- 前端笔记之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 ...
- JavaScript中的Generator函数
1. 简介 Generator函数时ES6提供的一种异步编程解决方案.Generator语法行为和普通函数完全不同,我们可以把Generator理解为一个包含了多个内部状态的状态机. 执行Genera ...
- js-ES6学习笔记-Generator函数
1.Generator 函数是 ES6 提供的一种异步编程解决方案.形式上,Generator 函数是一个普通函数,但是有两个特征.一是,function关键字与函数名之间有一个星号:二是,函数体内部 ...
- Generator函数执行器-co函数库源码解析
一.co函数是什么 co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行.短小精悍只有短短200余行,就可以免去手动编写G ...
- 15.Generator 函数的语法
Generator 函数的语法 Generator 函数的语法 简介 基本概念 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.本章详细介绍 Generat ...
随机推荐
- Android使用TextView实现跑马灯效果(自定义控件)
对于一个长的TetxView 折行显示是一个很好的办法,另一种方法就是跑马灯显示(单行滚动) 1.折行显示的长TextView <LinearLayout xmlns:android=" ...
- Python第三方库jieba(中文分词)入门与进阶(官方文档)
jieba "结巴"中文分词:做最好的 Python 中文分词组件 github:https://github.com/fxsjy/jieba 特点 支持三种分词模式: 精确模式, ...
- java基础 运算符
算数运算符 加号:在操作数值.字符.字符串时其结果是不同的,当两个字符相加得到的是ASCII码表值, 当两个字符串相加时表示将两个字符串连接在一起,从而组成新的字符串. 除号:整数在使用除号操作时,得 ...
- python 学记笔记 SQLalchemy
数据库表是一个二维表,包含多行多列.把一个表的内容用Python的数据结构表示出来的话,可以用一个list表示多行,list的每一个元素是tuple,表示一行记录,比如,包含id和name的user表 ...
- MVC 从控制器将数据对象赋值给前端JS对象
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport&quo ...
- 微信小程序实现图片上传,预览,删除
wxml: <view class='imgBox'> <image class='imgList' wx:for="{{imgs}}" wx:for-item= ...
- hdu 1506(好题+DP或者RMQ)
Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- JMeter------ _time 函数的使用(时间戳、当前时间)
操作步骤: 1.通过函数助手,生成一个_time 函数: 2.如果参数为时间戳,那公式为: ${__time(,)} : 默认该公式精确到毫秒级别, 13位数 ${__time(/1000,)} ...
- ionic3包还原使用yarn命令执行步骤(解决ionic3懒加载报找不到 module的错误)
使用cnpm 还原ionic3.6的依赖包的时候 可以正常还原,但是使用懒加载就会报找不到 module 的错误.最简单的解决办法是删除node_modules 挂个vpn 重新执行npm insta ...
- 解决Django在mariadb创建的表插入中文乱码的问题
1.确保你的mariadb数据库的character_set_connection.character_set_database.character_set_server的编码均为utf8 Maria ...