generator函数
函数的执行顺序
function *test(){
console.log(0);
yield console.log(2);
console.log(3);
yield console.log(4);
console.log(5);
return 12345 // 会被当做最后一次next过后的value值
}
var a = test();
console.log(a.next());
console.log(a.next());
console.log(a.next());
执行的结果如下图所示
每一个yield都会暂停一次函数的执行,调用一次next(),就会执行对应第几个的yield后面与前面的代码。n个yield需要(n+1)个next()来执行,return后面的代码不会执行,并且return的返回值会被当做最后一个next执行的 value
next() 可以传递参数,但是参数需要再每一个yield函数前面定义
/**
*1. 第一个next() 的参数只能通过generator 函数直接传入
*2. 么一个yield 前面定义的值就是下一个 next() 执行的参数
*/
function *params(params){
let a = yield params; // 前面的a是下一次next的参数
let { name,age } = yield a;
yield { name,age }
return [1,2,3]
}
let gen = params('first')
console.log(gen.next()) // { value: 'first', done: false }
console.log(gen.next('second')) // { value: 'second', done: false }
console.log(gen.next({name:'chenkang',age:20})) // { value: { name: 'chenkang', age: 20 }, done: false }
console.log(gen.next()) // { value: [ 1, 2, 3 ], done: true }
模拟co函数的执行,只考虑后面跟随了promise的版本
function co(generator){
let gen = generator();
function next(data){
let p = gen.next(data); //由上面参数部分可以知道,每一个传入next()的参数都会被yield前面的变量接收
if(p.done){
return
}
p.value.then( data=>{
next(data.data) // 递归调用,接收上一个promise函数的返回值作为下一个next()的参数,就可以在yield前面的变量获取到这一个值
})
}
next(); // 第一次执行的时候不需要参数
}
function *getData(){
let firstData = yield axios.get('https://api.myjson.com/bins/1414ti');
console.log(data); // { name:'chenkang',age:20 }
}
co(getData)