ES6——Generator

概念

通俗来讲,这就是异步编程的一种解决方案。

早期方式是通过回调,es6新增加了Promise,而Generator也是用于异步编程的,但更高级一点。


Generator包含多个步骤,每个步骤的标志就是yield或return。

遇到yieldreturn,就会停止运行

进入下一步的时候,需要调用next( )



使用方法


基本定义


生成器函数以function *开头

返回值: Iterator结构数据


实例

//定义Generator
let tell = function* (){
    yield 'a';
    yield 'b';
    return 'c';
};

let k = tell();

console.log(k.next());  // {value: 'a' , done:false}
console.log(k.next());  // {value: 'b' , done:false}
console.log(k.next());  // {value: 'c' , done:false}
console.log(k.next());  // {value: undefined , done:true}



Generator && Iterator


之前讲过Iterator,它有一个缺点,就是需要自己创建接口。

而如果使用Generator,我们可以就不创建接口了。

使用方法

1. 对象调用[Symbol.iterator]

2. 对象赋值给Generator 


实例

let obj = {};
obj[Symbol.iterator]=function* (){
    yield 1;
    yield 2;
    yield 3;
}

for(let value of obj){
    console.log(value); // 1 2 3
}



状态机


当在yield外层加上while(1){}的时候,结果就会循环输出

而且永远不会结束


实例

 let state = function* (){
        while(1){
            yield 'A';
            yield 'B';
            yield 'C';
        }
    }

    let status =  state();
    console.log(status.next());  //{value: 'A' , done:false}
    console.log(status.next());  //{value: 'B' , done:false}
    console.log(status.next());  //{value: 'C' , done:false}
    console.log(status.next());  //{value: 'A' , done:false}
    console.log(status.next());  //{value: 'B' , done:false}



Async函数

与Generator相比,以async function开头,yield替换成await


实例

改写上面的例子

    let state = async function (){
        while(1){
            await 'A';
            await 'B';
            await 'C';
        }
    }

    let status =  state();
    console.log(status.next());
    console.log(status.next());
    console.log(status.next());
    console.log(status.next());
    console.log(status.next());

Async是ES7新增的内容,在此暂不做过多介绍,有待以后补充。



使用实例


1)抽奖次数限制

let draw = function(count){
    //具体抽奖逻辑
    console.log(`剩余${count}次`)
}

//使用Generator控制次数
let res = function* (count){
    //次数限制
    while (count>0){
        count--;

        //执行抽奖逻辑
        yield  draw(count);
    }
}

let star = res(5);
let btn = document.createElement('button');
btn.id = 'start';
btn.textContent='抽奖';
document.body.appendChild(btn);
document.getElementById('start').addEventListener('click',function(){
    star.next();
},false)

运行结果

依次打印出 剩余4次 剩余3次 剩余2次 剩余1次 剩余0次

剩余0次以后,无法触发抽奖。



2)查询服务器状态

查询服务器状态可以使用轮询、Websocket等方式。

之前也有写了相关博文Web实时通讯——轮询、WebSocket

在这里,我们使用Generator写长轮询。


代码

//模拟ajax
let ajax =function* (){
    yield  new Promise(function(resolve,reject){
        setTimeout(function(){
            //↓↓模拟客服端返回的状态码
            resolve({code:0})
        },220);
    })
}

let pull = function(){
    //Generator实例化
    let generator = ajax();

    //让generator执行一次,也就是模拟通信一次
    let step = generator.next();

    //↓↓step.value是Promise实例   
  //  ↓↓              ↓↓ function即是resolve,d即是参数集合
    step.value.then(function(d){
        //如果返回的code不是0,一秒后再次调用自身
        if(d.code!=0){
            setTimeout(function(){
                console.log('wait');
                pull()
            },1000)
        }
        else{
            console.log(d);
        }
    })
}
//调用
pull();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值