JavaScript之ES6中的生成器函数Generator

1、Generator定义

生成器函数Generator是一种异步编程的解决方案,比Promise更高级。

除了通过return 返回值之外,generator还可以通过yield多次返回值。

//function后紧跟*
function* hello(){
    yield ...;
    yield ...;
    ...       
};

2、常用API

generator实例通过 next() 方法一步一步执行yield,第1次next(),返回第1个yield和是否完毕的状态(true \false),第2次next(),返回第2个yield……,当全部返回值都访问后,状态才为true。

{
    let tell = function*(){
        yield 'a';//step1
        yield 'b';//step2
        return 'c';
    }
    let k = tell();//generator实例化
    console.log(k.next());// a false 执行第1个yield
    console.log(k.next());//b false 执行第2个yield
    console.log(k.next());//c true
    console.log(k.next());//undefined true
}

generator实例可以通过for……of遍历。

{
    //遍历器
    let obj ={};
    obj[Symbol.iterator] = function*(){
        yield 1;
        yield 2;
        yield 3;
    }
    for(let key of obj){
        console.log(key);//1 2 3
    }
}

3、用法

1、状态机

{
    //状态机
    let state = function*(){
        while(1){
            yield 'A';
            yield 'B';
            yield 'C';
        }
    }
    let status = state();
    console.log(status.next());//A
    console.log(status.next());//B
    console.log(status.next());//C
    console.log(status.next());//A
    console.log(status.next());//B
}

2、抽奖

{
    //抽奖逻辑,抽奖次数限制
    let draw = function(count){
        //具体抽奖逻辑
        console.info(`剩余${count}次`);
    }
    let residue = function*(count){
        while(count>0){
            count --;
            yield draw(count);
        }
    }
    let start = residue(5);//实例化
    let btn = document.createElement('button');
    btn.id = 'start';
    btn.textContent = '抽奖';
    document.body.appendChild(btn);
    document.getElementById('start').addEventListener('click',function(){
        start.next();
    },false)
}

3、长轮询

{
    //定时获取服务端变化,长轮询
    let ajax = function*(){
        yield new Promise(function(resolve,reject){
            setTimeout(function(){
                resolve({code:0});
                //resolve({code:1});//每隔1200ms输出一个wait
            },200);
        })
    }
    let pull = function(){
        let generator = ajax();//generator实例化
        let step = generator.next();//next()方法
        step.value.then(function(d){ //step.value即为Promise实例
            if(d.code != 0){
                setTimeout(function(){
                console.log('wait');
                pull();
                },1000)
            }else{
                console.info(d);//code 0
            }
        })
    }
    pull();
}
posted @ 2018-03-28 10:29  你是海上的烟火  阅读(497)  评论(0编辑  收藏  举报