ES6_11、生成器函数的声明与调用

生成器

生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
异步编程:比如:文件操作、网络操作(ajax,request)、数据库操作。
如:

        function * gen(){
            console.log("hello");
        }

        //调用
        let iterator=gen();
        iterator.next();

yield

函数代码的分隔符,配合neext来控制代码执行,相当于对一大块代码一次只执行其中一部分。(next调用一次执行一部分)。next返回的是一个对象,里面包括value和done属性。
遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值作为返回的对象的value属性的值。

//yield:
        function * gen(){

            console.log(111);
            yield '分隔符1';

            console.log(222);
            yield '分隔符2';

            console.log(333);
            yield '分隔符3';

            console.log(444);
        }


        //调用
        let iterator=gen();
        
         iterator.next();
         iterator.next();
         iterator.next();
         iterator.next();

image

应用返回的是一个迭代器对象,所以可以直接for of遍历

//应用返回的是一个迭代器对象,所以可以直接for of遍历
        for (const v of gen()) {
             console.log(v);
        }

特点

生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到
yield 语句后的值。

yield 相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次 next
方法,执行一段代码。

next 方法可以传递实参,作为 yield 语句的返回值。

生成器函数的参数传递

生成器模式是对象创建软件设计模式,其目的是找到伸缩构造器反模式的解决方案。
next传入的参数将作为上一个yeild语句的返回结果。

next方法可以传入实参,这个实参就是里面的某个yield的返回结果。第二次调用next方法传入的实参将作为第一个yield语句整体的返回结果,第三次调用next方法传入的实参将作为第二个yield语句整体的返回结果...

image



实例1

1s后控制台输出111,2s后输出222,3s后输出333,整个过程完成时间为6s

常用方法:
image
上面这种做会造成回调地狱。


合适做法

            function one(){setTimeout(() => {
                console.log(111);
                g.next();//因为函数里只是定义,没有调用 调用的时候g已经定义好了
            }, 1000);}

            function two(){setTimeout(() => {
                console.log(222);
                g.next();
            }, 2000);}

            function three(){setTimeout(() => {
                console.log(333);
                g.next();
            }, 3000);}


            function * gen(){                

                yield one();//加括号表示调用函数               

                yield  two();

                yield three();
            }

            let g=gen();
             g.next();

image



实例2、模拟获取数据,顺序:用户数据->订单数据->商品数据

        function getUsers(){
            setTimeout(() => {
                let data="用户数据";
                g.next(data);
                
            }, 1000);
        }

        function getOrders(){
            setTimeout(() => {
                let data="订单数据";
                g.next(data);
                
            }, 1000);
        }

        function getGoods(){
            setTimeout(() => {
                let data="商品数据";
                g.next(data);
                
            }, 1000);
        }

        function * gen(){
           let users= yield getUsers();//得到用户数据
           console.log(users);
           let order=yield getOrders();//得到订单数据
            console.log(order);
            let good=yield getGoods();//得到商品数据
            console.log(good);
        }

        let g=gen();
        g.next();
posted @ 2022-03-17 19:31  青仙  阅读(92)  评论(0编辑  收藏  举报