generator

generator生成器

1、基本概念

执行Generator函数会返回一个迭代器对象,也就是说,Generator函数还是一个迭代器对象生成的函数,返回的迭代器对象,可以依次遍历Generator函数内部的每一个状态,生成器也是一个函数

跟普通函数的区别

1、function关键字与函数名之间有一个星号
2、函数体内部使用yield表达式,定义不同的内部状态
3、·Generator·函数不能跟new一起使用,会报错

2、generator的基本使用

(1)定义generator函数

function关键字和函数名之间加一个*号就表示这是一个generator函数

function * show(){
	yield 语句;
	yield 语句;
}

(2)generator函数的调用

        function * show(){
            yield 1;
            yield 2;
            yield 3;
        }
        let p=show();
        console.log(p);
        //generator对象上p有一个next方法,执行后返回一个对象,对象里是一个yield值value属性和done属性为false
        console.log(p.next());
        console.log(p.next());
        console.log(p.next());
        //当done属性为true时表示generator里面的内容执行完毕,如果还继续调用next方法,返回值value为undefined
        console.log(p.next());

在这里插入图片描述

(3)generator函数批量处理yield

注意:yield关键字只能在生成器generator函数中使用,否则会报错

        function * show(arr){
            for(let i=0;i<arr.length;i++){
                yield arr[i];
            }
        }
        let p=show([1,2,3,4]);
        console.log(p);
        console.log(p.next());

在这里插入图片描述

(4)generator函数表达式

除了可以通过函数声明的方式创建生成器的函数,也可以通过函数表达式创建generator生成器
注意:不能通过箭头函数创建生成器

        let show=function *(arr){
            for(let i=0;i<arr.length;i++){
                yield arr[i];
            }
        }
        let p=show([1,2,3,4]);
        console.log(p);
        console.log(p.next());

(5)generator不同的调用

循环

for...of适合generator循环,但是不会遍历return后面的内容

        function * show(){
            yield 1;
            yield 2;
            yield 3;
        }
        let p=show();
        for(let val of p){
            console.log(val);
        }

在这里插入图片描述

解构
        function * show(){
            yield 1;
            yield 2;
            yield 3;
        }
        let p=show();
        let [a,b,c]=show();
        console.log(a,b,c);

在这里插入图片描述

扩展运算符
        function * show(){
            yield 1;
            yield 2;
            yield 3;
        }
        let p=show();
        console.log(...p);

在这里插入图片描述

Array.from()
        function * show(){
            yield 1;
            yield 2;
            yield 3;
        }
        let p=show();
        console.log(Array.from(p));

在这里插入图片描述

(6)对象的生成器方法

对象生成器方法

由于生成器本身就是函数,因此可以添加到对象中,成为对象的方法

        let obj={
            // createIterator:function *(arr){
            //     for(let i=0;i<arr.length;i++){
            //         yield arr[i]
            //     }
            // }
            //也可用ES6对象方法简写创建生成器
             *createIterator(arr){
                for(let i=0;i<arr.length;i++){
                    yield arr[i]
                }
            }
        }
        let iterator=obj.createIterator([1,2,3]);
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());

在这里插入图片描述

可迭代对象和for…of循环

具有Symbol.iterator方法的对象,通过这个方法可以创建一个迭代器对象.因此所有通过生成器创建迭代器都是迭代对象, 诸如字符串, 数组,Set,Map ,都默认具有迭代器,

for...of 循环的本质就是通过每次调用迭代对象的next()方法, 并将迭代器返回的 结果对象中的value属性值存到一个变量中, 循环执行直到结果对象中done属性值为true为止

let arr = [10,20,30]
for(let num of arr){
    console.log(num)
}

(7)generator生成器处理异步

 function run(generator){
            let obj=generator();
            console.log('obj',obj);

            //执行第一次
            let res=obj.next();
            console.log('res',res);

            //递归调用判断done是否为true执行完毕
            function step(){
                if(!res.done){
                    //判断res.done是否为true,是就执行完毕,不是就继续递归调用step函数迭代
                    res=obj.next();
                    console.log(res);
                    step();
                }
            }
            step();
        }

        run(
            //生成一个生成器,传入到run函数generator
            function *(){
                yield 10;
                yield 20;
                yield 30;
            }
        )

在这里插入图片描述

处理本地异步程序
        //generator处理本地异步程序
        function asyncFun(num){
            return function(cb){
                setTimeout(function(){
                    cb(num)
                },1000)
            }
        }
        // let fn=asyncFun(10);
        // fn(function(val){
        //   console.log(val);
        // });

        //处理generator函数
        function run(generator){
            let obj=generator();
            console.log('obj',obj);

            //执行第一次
            let res=obj.next();
            console.log('res',res); //{value:f(){};done:false;} value是asyncFun函数return出来的函数

            //递归调用判断done是否为true执行完毕
            function step(){
                //判断res.done是否为true,是就执行完毕,不是就继续递归调用step函数迭代
                if(!res.done){
                    
                    //判断value的值是否为函数
                    if(typeof res.value=='function'){
                        res.value(function(val){
                            console.log(val);
                            res=obj.next(val);
                            console.log(res);
                            step();
                        })
                    }
                   
                }
            }
            step();
        }

        run(
            //生成一个生成器,传入到run函数generator
            function *(){
                let res=yield asyncFun(10);
                res=yield asyncFun(res+10);
                res=yield asyncFun(res+10);
                console.log(res);
            }
        )

在这里插入图片描述

处理ajax请求
结合promise处理异步程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值