es6-生成器

生成器

  • 本身是一个函数,是es6提供的一个异步解决方案,和传统函数完全不同
  • 作用是用来做异步编程的

生成器的使用

  • 定义生成器函数 需要在function 后面添加 * 号
    function* gen() {
        console.log('这是一个生成器函数,并且是第一段');
        // 可以出现yield语句 后面跟字面量 或者 表达式
        yield '李明凯'
        console.log('第二段');
        yield '凯明李'
        console.log('第三段');
        // yield 算作函数代码的分隔符 就是分隔函数内的代码
    }
  • 执行生成器函数
    // 函数执行结果 特殊
    let iter = gen();
    console.log(iter); // 返回的是一个迭代器对象
    // 运行的话 需要借助 迭代器中的 next方法
    iter.next(); // 输出 结果
    iter.next();
    iter.next();
    
    // 可以通过 for of 做一个 遍历
    for (let v of gen()) {
        console.log(v); // 每次调用的返回结果是 yield表达式
    }

生成器函数参数

  • 可以给生成器函数传入参数,也可以给next方法传入参数
  • 生成器函数传入的函数和普通函数参数一样可以调用
  • next方法传入的参数会称为 yield的返回值
  • 声明一个生成器函数
    function* gen(arg) {
        console.log(arg); // 打印传入的参数
        let one = yield 111; // 通过变量接收返回结果
        console.log(one); // 打印返回结果
        let two = yield 222;
        console.log(two);
        yield 333;
    }
  • 执行获取迭代器对象
    // 执行获取迭代器对象
      let lr = gen('aaa'); // 传入一个实参
    
      // next参数可以传入实参,这个实参就是yield语句的返回结果
      console.log(lr.next());
      console.log(lr.next('bbb')); // 第二个next参数传入的实参是 第一个yield语句的返回结果
      console.log(lr.next('ccc')); // 第三个next参数传入的实参是 第二个yield语句的返回结果
      console.log(lr.next('ddd')); // 第四个next参数传入的实参是 第三个yield语句的返回结果

生成器案例

  • 1s后控制台输出 111 2s后控制台输出 222 3秒后控制台输出 333 定时器案例

  • 不用生成器做的话

    // 这种被称为回调地狱
    setTimeout(() => { // 箭头函数
        console.log(111);
        setTimeout(() => {
            console.log(222);
            setTimeout(() => {
                console.log(333);
            }, 1000);
        }, 1000);
    }, 1000);
    // 虽然可以实现功能,但是不易于维护
  • 使用生成器

  • 声明三个函数

    // 声明三个函数
        function one() {
            setTimeout(() => {
                console.log(1);
                lr.next(); // 在函数中再次调用生成器函数的next方法
            }, 1000);
        }
    
        function two() {
            setTimeout(() => {
                console.log(2);
                lr.next(); // 在函数中再次调用生成器函数的next方
            }, 1000);
        }
    
        function three() {
            setTimeout(() => {
                console.log(3);
                lr.next(); // 在函数中再次调用生成器函数的next方
            }, 1000); 
        }
  • 定义生成器函数

    // 定义生成器函数
    function* gen() {
        // 调用三个函数
        yield one();
        yield two();
        yield three();
    }
  • 调用生成器函数

    // 调用生成器函数
       let lr = gen();
       lr.next(); // 这里值执行了第一个 函数 如果 需要执行后面的需要再次调用.可以在函数中调用
  • 获取用户数据,获取订单数据,获取商品数据

  • 定义三个函数

    function getUser() {
        setTimeout(() => {
            let data = '用户数据';
            lr.next(data) // 调用next方法,并将数据传入
        }, 1000);
    }
    
    function getOrder() {
        setTimeout(() => {
            let data = '订单数据';
            lr.next(data) // 调用next方法,并将数据传入
        }, 1000);
    }
    
    function getgood() {
        setTimeout(() => {
            let data = '商品数据';
            lr.next(data); // 调用next方法,并将数据传入
        }, 1000);
    }
  • 声明生成器函数

    function* gen() {
        let users = yield getUser();
        console.log(users);
        let dd = yield getOrder();
        console.log(dd);
        let sp = yield getgood();
        console.log(sp);
    }
  • 调用生成器函数

    // 调用生成器函数
    let lr = gen();
    lr.next(); // 第一次调用后会调用第一个yield,然后通过函数再次调用next方法,并传入参数

本博客所有文章是以学习为目的,如果有不对的地方可以一起交流沟通共同学习 邮箱:1248287831@qq.com!