版权声明:未经本人同意不得私自转载 https://blog.csdn.net/qq_40190624/article/details/82846948
一般的函数只有一次返回值 ,但是我们的generator可以给我们返回多次
做一个简单的相亲网Demo会更明白一些:https://gitee.com/CarrieProject/generator/branches
1.generator的结构为
function* numbers(){//一个* 和一个对应的名字;
// yield为生成器中的关键字
}
//然后一个生成器
const gen = numbers();
//gen并不是像ES5中为一个方法,这里打印并不需要()
console.log(gen)
function* nmubers(){
// yield为生成器中的关键字
// yield;
}
const gen = nmubers();//gen并不是像ES5中为一个方法,这里打印并不需要()
console.log(gen.next())//{value: undefined, done: false}
console.log(gen.next())//{value: undefined, done: true}
//以上为什么同样的东西打印出来却有两种结果?如果你把方法里的yield关键字注释后再打印你会发现两次结果都为true
生成器适用场景有斐波那契数列的道理,意思是前两个数相加等于第三个数,以此相加
(0,1,1) -->0+1=1.1+1=2 这样的算法
我们先用ES5的方式写一个看看;
//斐波那契数列
function fib(max){
//a和b为初始值,因为ES5中没有办法返回多个值,所以我们需要一个数值方式返回回去;数组里的初始值也是一开始固定好了的也是斐波那契的一个固定写法;
var a = 0,b = 1, arr =[0,1];
while(arr.length < max){
/**
* b给到a然后把我们的a和b相加, 把Bpush到我们的arr里去;因为b每次都加增加
*/
[a,b] = [b,a + b];
arr.push(b);
}
return arr;
}
//斐波那契最开始都是(0,1,1,2,3)-->0+1=1,1+1=2 这样的一个过程
console.log(fib(5))//[ 0, 1, 1, 2, 3 ]
console.log(fib(10))//[ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
es6方式
function* fib(max){
var a = 0 , b = 1, n = 0;
while (n<max){
//当yield返回值的时候为false,不再返回的时候才为true
yield a;//此时a不停的在发生变化,a返回回去,b的值赋给了a
[a,b] = [b,a + b];
n++;
}
return;
}
let f = fib(5)
//想打印对应的值可以使用for of
for(var x of fib(10)){
console.log(x)
}//[ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
如果以上不能够理解我们可以用ES5还原一下 generator的原理:
/**
* 迭代器还原生成器的结构
*/
function nameIterator(names){
let nextIndex = 0;
return {
next:function(){
return nextIndex < names.length?
{value:names[nextIndex++],done:false} :
{value:'undefined',done:true}
}
}
}
const nameArray = ['Henry','Bucky','Emily'];
const names = nameIterator(nameArray);
console.log(names.next())//{ value: 'Henry', done: false }
console.log(names.next())//{ value: 'Bucky', done: false }
console.log(names.next())//{ value: 'Emily', done: false }
console.log(names.next())//{ value: 'undefined', done: true }
console.log(names.next())//{ value: 'undefined', done: true }
demoTwo
//demo Two
function* sayNames(){
yield 'Henry';
yield 'Bucky';
yield 'Emily';
}
const name = sayNames();
console.log(name.next())
console.log(name.next())
console.log(name.next())
/**
* { value: 'Henry', done: false }
{ value: 'Bucky', done: false }
{ value: 'Emily', done: false }
*/