//Generator的简单语法
console.log("=========Generator的简单语法============")
//yield定义的表达式,只有next()函数才能执行直接调用 function* 的函数无法执行
function* helloWorldGenerator() {// 使用 function* 关键字定义Generator函数
yield 'hello'; // 使用yield关键字 定义不同的内部状态
yield 'world';
return 'end'; // 停止该状态
}
var hw = helloWorldGenerator();
console.log(hw.next());
console.log(hw.next());
console.log(hw.next());
console.log(hw.next());
/*
{ value: 'hello', done: false }
{ value: 'world', done: false }
{ value: 'end', done: true }
{ value: undefined, done: true }
*/
//Generator的应用==》遍历一维+二维数组
console.log("=========Generator的应用==》遍历一维+二维数组============")
let arrYield = [1, [[2, 3], 4], [5, 6]];
let flat = function* (arr) {
let length = arr.length;
for (let i = 0; i < length; i++) {
let item = arr[i];
if (typeof item !== 'number') {
yield* flat(item);
} else {
yield item;
}
}
}
for (let f of flat(arrYield)) {
console.log(f);//1,2,3,4,5,6
}
//简单的Iterator函数生成方式
console.log("=========简单的Iterator函数生成方式============")
let myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
yield 4;
}
console.log([...myIterable]);//[1,2,3,4]
//Generator函数与Iterator接口的关系
console.log("=========Generator函数与Iterator接口的关系============")
function* gen() {}
let g = gen();
console.log(g[Symbol.iterator]() == g); //true
//next(true)返回上一个yield表达式的返回值
console.log("=========next(true)返回上一个yield表达式的返回值============")
function* previousYieldValue() {
for (let i = 0; true; i++) {
let reset = yield i;//reset 为next()函数传入的值
console.log("reset",reset);
if(reset) {i = i-2};
}
}
let previousValue = previousYieldValue();
console.log(previousValue.next());
console.log(previousValue.next());
console.log(previousValue.next());
console.log(previousValue.next(true));
console.log(previousValue.next());
/*
{ value: 0, done: false }
reset undefined
{ value: 1, done: false }
reset undefined
{ value: 2, done: false }
reset true
{ value: 1, done: false }
reset undefined
{ value: 2, done: false }
*/
// next()函数是用于向generator函数进行状态变化时的过程中
// next()方法的参数表示上一个yield表达式的返回值,所以第一次使用next方法时,传递参数是无效的
// yeild定义的表达式将在next()函数调用时,将结果返回给next()函数,但不会再generator中执行
console.log("=========next()函数是用于向generator函数进行状态变化时的过程中 改变yield表达式内部值得一种方式============");
function* nextFoo(x) {
let y = 2 * (yield(x + 1));
let z = yield (y / 3);
return (x + y + z);
}
let nextFA = nextFoo(5);
console.log(nextFA.next());
console.log(nextFA.next());
console.log(nextFA.next());
/*
{ value: 6, done: false }
{ value: NaN, done: false }
{ value: NaN, done: true }
*/
let nextFB = nextFoo(5);
console.log(nextFB.next());
console.log(nextFB.next(12));//设置上一个yield(x+1)的值为12 所以y为24 ->当前返回z = 8
console.log(nextFB.next(13));//设置上一个yield的值为13即z=13 x+y+z = 5+24+13 = 42
/*
{ value: 6, done: false }
{ value: 8, done: false }
{ value: 42, done: true }
*/
//使用next方法向函数内部输入值得例子
function* dataConsumer() {
console.log('Started');
console.log(`1.${yield 222}`);
console.log(`2.${yield}`);
}
let consumer = dataConsumer();
console.log(consumer.next());
console.log(consumer.next('a'));
console.log(consumer.next('b'));
/*
Started
{ value: 222, done: false }
1.a
{ value: undefined, done: false }
2.b
{ value: undefined, done: true }
*/
//要想第一个next()就可以传值的写法
function wrapper(generatorFunction) {
return function (...args) {
let generatorObject = generatorFunction(...args);
generatorObject.next();
return generatorObject;
};
}
const wrapped = wrapper(function* () {
console.log(`First input: ${yield}`);
return 'DONE';
})
console.log(wrapped().next('hello~'));
/*
First input: hello~
{ value: 'DONE', done: true }
*/
console.log("===========for...of循环自动遍历Generator函数,不需要使用next方法=============")
//for...of循环自动遍历Generator函数,不需要使用next方法
function* forOf() {
yield 1;
yield 2;
return 3;
}
for (let v of forOf()) {
console.log(v);//1,2
}
/*
只显示了2个yield表达式的值,一旦next方法返回对象done属性为true,for...of循环就会终止,且不会返回该对象,所以return不包括在for...of循环中
*/
//使Object能使用for...of进行遍历
console.log('=====================使Object能使用for...of进行遍历========================');
function* objectEntries(obj) {
let propKeys = Reflect.ownKeys(obj);
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*/
}
//Generator.prototype.throw()方法
console.log("==========Generator.prototype.throw()方法==================")
let throwFunction = function* () {
try {
yield 1;
}catch (e) {
console.log('内部捕获',e)
}
yield 2;
};
let i = throwFunction();
i.next();
try {
console.log(i.throw('a'));//执行generator的catch方法后 自动执行下一个yield
i.throw('b');//因为generator的catch方法已经执行过了,所以抛出异常
} catch (e) {
console.log("外部捕捉",e);
}
/*
内部捕获 a
外部捕捉 b
*/
let i2 = throwFunction();
try {
console.log(i2.throw('c'));//执行generator的catch方法后 自动执行下一个yield
}catch (e) {
console.log("外部捕获", e);//外部捕获 c,因为未执行next方法,仍未到Generator函数内部
}
let i3 = throwFunction();
console.log(i3.next());
console.log(i3.next());
try{
console.log(i3.throw('D'))//执行generator的catch方法后 自动执行下一个yield
}catch (e) {
console.log('外部捕获', e);//外部捕获 D 因为第2个next外部没有try...catch语句
}
/*
内部捕获 a
{ value: 2, done: false }
外部捕捉 b
外部捕获 c
{ value: 1, done: false }
{ value: 2, done: false }
外部捕获 D
*/
//Generator.prototype.return() 终结遍历Generator函数
function* returnFunction() {
yield 1;
yield 2;
yield 3;
}
let returnFun = returnFunction();
console.log(returnFun.next());
console.log(returnFun.return('foo'));
console.log(g.next());
//如果Generator函数内部哟try...finally代码块,且正在执行try代码块,那么return方法会推迟到finally代码块执行完在执行
function* numbers() {
yield 1;
try {
yield 2;
yield 3;
}finally {
yield 4;
yield 5;
}
yield 6;
}
let numb = numbers();
console.log(numb.next());
console.log(numb.next());
console.log(numb.return(7));
console.log(numb.next());
console.log(numb.next());
/*
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 4, done: false }
{ value: 5, done: false }
{ value: 7, done: true }
*/
//yield* 表达式 如果在Generator函数内部,调用另一个Generator函数,需要在前者的函数体内部,自己手动完成遍历
console.log("================yield* 表达式===================")
function* iteratorFunction() {
yield 'a';
yield 'b';
}
function* barFunction() {
yield 'x';
for (let i of iteratorFunction()) {
console.log(i);//a,b
}
yield 'y';
}
for (let v of barFunction()) {
console.log(v);//x,a,b,y
}
let stringsBarFunction = barFunction();
console.log(stringsBarFunction.next());
console.log(stringsBarFunction.next());
console.log(stringsBarFunction.next());
console.log(stringsBarFunction.next());
/*
{ value: 'x', done: false }
a
b
{ value: 'y', done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
*/
//使用 yield* 只要有Iterator接口就能实现遍历
function* yieldFunction() {
yield 'x';
yield* iteratorFunction();
yield 'y';
}
//等同于
function* yieldBarFunction() {
yield 'x';
yield 'a';
yield 'b';
yield 'y';
}
//等同于
function* yieldBarForFunction() {
yield 'x';
for (let v of yieldFunction()) {
yield v;
}
yield 'y';
}
for (let v of yieldFunction()) {
console.log('yieldFunction', v);//x,a,b,y
}
let yieldFunction1 = yieldFunction();
console.log(yieldFunction1.next());
console.log(yieldFunction1.next());
console.log(yieldFunction1.next());
console.log(yieldFunction1.next());
/*
{ value: 'x', done: false }
{ value: 'a', done: false }
{ value: 'b', done: false }
{ value: 'y', done: false }
*/
//另一个例子
function* inner() {
yield 'hello!';
yield 'hello1!';
}
function* outer1() {
yield 'open';
yield inner();
yield 'close';
}
let genOuter = outer1();
console.log(genOuter.next().value);//open
console.log(genOuter.next().value);//Object [Generator] {}
console.log(genOuter.next().value);//close
function* outer2() {
yield 'open';
yield* inner();
yield 'close';
}
let genOuter2 = outer2();
console.log(genOuter2.next().value);//open
console.log(genOuter2.next().value);//hello!
console.log(genOuter2.next().value);//hello1!
console.log(genOuter2.next().value);//close
//如果被代理的Generator函数有return语句,那么久可以向代理它的Generator函数返回数据
function* fooReturn() {
yield 2;
yield 3;
return 'fooReturn';
}
function* barFunctionReturn() {
yield 1;
let v = yield* fooReturn();
console.log('v: ' + v);
yield 4;
}
let it = barFunctionReturn();
console.log(it.next());//{ value: 1, done: false }
console.log(it.next());//{ value: 2, done: false }
console.log(it.next());//{ value: 3, done: false }
//v: fooReturn
console.log(it.next());//{ value: 4, done: false }
console.log(it.next());//{ value: undefined, done: true }
//作为对象属性的Generator函数简写成以下形式
let objGenerator = {
* myGeneratorMetod() {
},
myGeneratorMetod2:function* () {
}
}
//9.generator函数的this
//10.generator函数的含义
//11.Generator与上下文
//12应用
Generator函数
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 廖雪峰老师----JavaScript教程 一.sort() 排序的核心?比较两个元素的大小 问题: 因为:Arr...
- Symbol Iterator遍历器 Generator函数 async函数 class 通过class定义类/实...
- generator函数 yield next() 可以控制代码执行的暂停与恢复,但不改变执行顺序 async aw...
- 让我们来想想generator函数和async有啥区别?唯一的区别是async函数会自动执行,而generator...
- 参考链接:http://www.ruanyifeng.com/blog/2015/04/generator.htm...