Generator生成器基础

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同

生成器函数声明与调用

 function* gen() {
 	console.log('hello');
 }
 let iterator = gen();
 console.log(iterator);//不会输出hello 是一个迭代器对象 需要调用next方法才会输出 
 iterator.next();

输出结果:

yield

yield相当于函数代码的分隔符

function* gen() {
    console.log('11111');   
    yield '求各路';
    console.log('22222');
    yield '神仙';
    console.log('55555');
    yield '保佑我';
    console.log('66666');
    yield '找工作顺利'

}
let iterator = gen();
iterator.next(); //第一次调用next 11111
iterator.next(); 
iterator.next(); 
iterator.next(); 
iterator.next(); 

yield将函数分割为:

结果:

因为是迭代器对象,所以可以遍历

function* gen() {
    
    yield '求各路';
  
    yield '神仙';
  
    yield '保佑我';
   
    yield '找工作顺利'

}
let iterator = gen();
for(let v of iterator){
       console.log(v);
}

每一次调用返回的结果是yield后面的表达式

这样更清楚:

function* gen() {
    
    yield '求各路';
  
    yield '神仙';
  
    yield '保佑我';
   
    yield '找工作顺利'

}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

生成器函数的参数传递

整体函数和next方法都可以传参

function *gen(arg) {
    console.log(arg);
    let r1  = yield 1111;
    console.log(r1);
    let r2 = yield 2222;
    console.log(r2);
    let r3 = yield 3333;
    console.log(r3)
}
let iterator = gen('AAA');
console.log(iterator.next());
//next方法可以传入实参
console.log(iterator.next('BBB')); //第二次调用next传入的参数作为第一个yield语句整体返回的结果
console.log(iterator.next('CCC')); //第三次调用next传入的参数作为第二个yield语句整体返回的结果
console.log(iterator.next('DDD')); //第四次调用next传入的参数作为第三个yield语句整体返回的结果

生成器函数在异步编程中的表现

常见异步编程 文件操作 网络操作 (ajax,request) 数据库操作

栗子1:

//1s后后台打印1111  2s后打印2222 3s后打印3333
//解决回调地狱
/*setTimeout(function () {
        console.log('1111');
        setTimeout(function () {
            console.log('2222');
            setTimeout(function () {
                console.log('3333');
            },3000)
        },2000)
    },1000);*/

function one() {
    setTimeout(() => {
        console.log('1111');
        iterator.next();
    },1000)
}
function two() {
    setTimeout(() => {
        console.log('2222');
        iterator.next();
    },2000)
}
function three() {
    setTimeout(() => {
        console.log('3333');
        iterator.next();
    },3000)
}

function *gen() {
    yield one();
    yield two();
    yield three();
}
let iterator = gen();
iterator.next();

栗子2:

//模拟 获取用户数据 再订单数据 再商品数据 是有先后顺序的
 function getUsers() {
     setTimeout(() => {
        let data =  '用户数据';
        //调用next方法,并将data传入,方便在外部操作数据
        iterator.next(data); //这个实参将作为第一个yield返回结果
     },1000)
 }
 function getOrders() {
     setTimeout(() => {
         let data = '订单数据';
         iterator.next(data);
     },1000)
 }
 function getGoods() {
     setTimeout(() => {
        let data = '商品数据';
        iterator.next(data);
     },1000)
 }

 function *gen(){
     let users = yield getUsers();
     console.log(users);
     let orders = yield getOrders();
     console.log(orders);
     let goods = yield getGoods();
     console.log(goods);
 }

 let iterator = gen();
 iterator.next();
原文地址:https://www.cnblogs.com/wahaha-/p/14028071.html