zoukankan      html  css  js  c++  java
  • 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();
    
  • 相关阅读:
    Linux下的目录结构
    VM
    代码命名规范
    java环境及配置
    Code::Blocks 使用Cygwin编译加调试
    vscode使用体会
    openwrt编译笔记
    ubuntu20 使用root登录
    程序员如何更好的表达自己的想法- Graphviz:关系图脚本绘制工具-转
    编译codelite心得
  • 原文地址:https://www.cnblogs.com/wahaha-/p/14028071.html
Copyright © 2011-2022 走看看