ES6新特性_生成器函数

ES6新特性_生成器函数

本文主要介绍,ES6新特性生成器函数,生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统的函数完全不同。生成器就是一个特殊的函数,用于解决异步编程的回调地狱。
生成器函数的声明, 在function与函数名之间加上一个*号
function * gen(){}
执行, 要想执行下面的打印,需要调用iterator的next方法
function * gen(){
    console.log('Hello Generator');
}

let iterator = gen();
iterator.next(); // Hello Generator
生成器函数yield
function * gen2(){
    console.log(111);
    yield '111'
    console.log(222);
    yield '222'
    console.log(333);
}

// 通过next调用一次只一个代码块
let iterator2 = gen2();
iterator2.next(); // 111
iterator2.next(); // 222
iterator2.next(); // 333

// 也可以使用for...of来遍历执行
for(v of gen2()){
    console.log(v); // 111,222,333
}
生成器函数参数
function * gen3(args){
    console.log(args); // aaaa
        
    // 接收next的参数
    let b = yield '111'
    console.log(b); // bbbb
            
    // 接收next的参数
    let c = yield '222'
    console.log(c); // cccc

}

// 传入参数
let iterator3 = gen3('aaaa');
iterator3.next();

// next方法也可以传入实参
iterator3.next('bbbb');

// next方法也可以传入实参
iterator3.next('cccc');
实例1

异步编程,常用的有:如文件操作,网络请求(ajax,request),数据库操作...等!
需求:1s后控制台输出111, 2s后输出222, 3s后输出333

  1. 如果没有使用生成器函数,如果有更多就要更多的嵌套形成回调地狱,不利于代码维护调试。
setTimeout(()=>{
    console.log(111);
    setTimeout(()=>{
        console.log(222);
        setTimeout(()=>{
        console.log(333);

        },3000)
    },2000)
},1000);
  1. 使用生成器来达到上面同样的效果,解决地狱回调的问题,代码也容易阅读和维护。
function one(){
    setTimeout(()=>{
        console.log(111);
        iterator4.next();
    },1000);
}
function two(){
    setTimeout(()=>{
        console.log(222);
        iterator4.next();
    },2000);
}
function three(){
    setTimeout(()=>{
        console.log(333);
        iterator4.next();
    },3000);
}
function * gen4(){
    yield one();
    yield two();
    yield three();
}
let iterator4 = gen4();
iterator4.next();
实例2

模拟获取: 用户数据,订单数据,商品数据
获取这三个数据是有顺序的,一般是要先获取用户数据,才能获取用户的订单,通过订单数据再获取订单关联的商品数据。

function getUsers(){
    setTimeout(()=>{
        let data = '用户数据';
        // 第二次调用 next 方法,并将数据传给下一个
        iterator5.next(data);
    }, 1000);
}
function getOrders(){
    setTimeout(()=>{
        let data = '订单数据';
        // 第三次调用next方法
        iterator5.next(data);
    }, 1000);
}
function getGoods(){
    setTimeout(()=>{
        let data = '商品数据';
        // 第四次调用next方法
        iterator5.next(data);
    }, 1000);
}
function * gen5(){
    let users = yield getUsers();
    console.log(users);

    let orders = yield getOrders();
    console.log(orders);

    let goods = yield getGoods();
    console.log(goods);
}
let iterator5 = gen5();
iterator5.next();
Loading...