js es6 生成器Generator函数
基本语法
Generator 函数有多种理解角度。首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。
Generator 函数是一个普通函数,但是有几个特征。
function关键字与函数名之间有一个星号;
函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”);
执行 Generator 函数会返回一个遍历器对象,可调用.next方法进行遍历, 遍历的结果是Generator函数里面通过yield或是return定义的值,按顺序输出
Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象(如下图),也就是上一章介绍的遍历器对象(Iterator Object)。
下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。每次调用next方法,内部指针从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。
function* bar(){
console.log("222");
yield "每天记得要用霸王";
//以yield为一个段落
console.log("333")
yield "保温杯里泡枸杞";//yield的值是保存在value中的。
console.log("444");
yield "人一定要骚话连篇";
return "程序的一生是悲凉的";//return 之后迭代器就无法执行了
}
//调用了生成器函数,函数并么有执行,返回了一个迭代器对象
let iterator=bar();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next().value);
yield表达式
1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。
3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。结束遍历
4)如果该函数没有return语句,则返回的对象的value属性值为undefined。
function *foo(){
yield "我是凯文";
yield "适应弹性工作";
yield "学会加班";
}
function *bar(){
yield* foo();
yield "提高效率";
yield "学会水去";
yield "凯文的凯文";
}
let iterator=bar();
for(let value of iterator){
console.log(value);
}
//
function foo(){
yield "aa";
return "养生";//语法能通过,但是写法是错误的
}
function* bar(){
console.log("程序员"+(yield 124));
yield 456;
//foo(yield "2",yield 3);
//let i=yield;里面不写值默认为undefined
}
let iterator=bar();
console.log(iterator.next());
console.log(iterator.next());
return yield
//都可以返回语句之后的那个值,一样的。但是return之后就无法取值,不一样的地方
next传参数
// next方法可以带一个参数,该参数可以被当作上一个yield语句的返回值
function *foo(){
console.log("START");
let args1= yield "我是凯文";
console.log(args1);//3
let args2= yield "适应弹性工作";
yield "学会加班";
}
let iterator=foo();
console.log(iterator.next(2));
console.log(iterator.next(3));
return 方法
//返回的参数 并且遍历结束遍历
//没有给参数返回就为未定义
function *foo(){
yield "我是凯文"
yield "适应弹性工作";
yield "学会加班";
}
let iterator=foo();
console.log(iterator.next());
console.log(iterator.return("结束"));
console.log(iterator.next());
throw
let g=function *(){
try{
yield new type(arguments);
yield 124;
}catch(e){//括号里面为捕获的一场
console.log(e);
}
finally{//报错后就一定会执行的
console.log("1244");
}
}
let iterator=g();
iterator.next();