es6的generator函数

原创
2018/08/08 16:43
阅读数 301

关于es6的generator函数

generator含义及用法

generator(生成器)是ES6标准引入新的数据类型, 一个generator看上去像一个函数,但可以返回多次。

  • generator使用function* 定义,除了return语句外,还可以用yield返回多次。

  • next()方法返回一个对象{value: x, done: true/false},其中value属性表示yield关键词后面表达式的值,done属性表示是否遍历结束。generator生成器通过next和yield的配合实现流程控制。next方法还可以接受参数,向generator内输入数据

  • throw('error')方法来抛出异常。当出现异常后,迭代中止,再次执行gen.next()时,将返回{value: undefined, done: true};

下面的列子中使用 function *gen(){...}定义了一个generator函数,在函数中使用了两个yield和return,就是说这个函数可以返回三次,即每次调用next()方法,函数就执行到yield语句的地方,然后暂停。

function* gen(){
    yield 'hello';
    yield 'world';
    return true;
}

var iter = gen();
var a = iter.next();
console.log(a);

var b = iter.next();
console.log(b);

var c = iter.next();
console.log(c);

使用generator函数解决异步回调问题

在这个例子中,generator函数中,yield后面返回的都是Promise,也就是说next()方法返回的value也是Promise,可以像处理promise的方式处理next()方法的返回值value,加上then回调处理。

function* gen(){
    yield $.get('http://v.beihaoyun.com/api/hosp/doctor/list?page=1&pageSize=4&status=1');
    yield $.get('http://v.beihaoyun.com/api/article/post/list?page=1&pageSize=4&article_category_id=10');
    yield $.get('http://v.beihaoyun.com/api/question/list2?page=1&pageSize=4&top_id=0&add_answer=true');
}


var g = gen();

g.next().value.then(res=>{
    console.log(res)
    g.next(res).value.then(resp=>{
        console.log(resp)
        g.next(resp).value.then(res2=>{
            console.log(res2)
        })
    })
})

上面的例子使用了手动调用next方法层层添加回调函数,下面写一个自动执行器

function* gen(){
    let a = yield $.get('http://v.beihaoyun.com/api/hosp/doctor/list?page=1&pageSize=4&status=1');
    let b = yield $.get('http://v.beihaoyun.com/api/article/post/list?page=1&pageSize=4&article_category_id=10');
    let c = yield $.get('http://v.beihaoyun.com/api/question/list2?page=1&pageSize=4&top_id=0&add_answer=true');
    console.log(a,b,c)
}

function run(gen){
    var g = gen();

    function next(data){
        var result = g.next(data);
        if(result.done)return result.value;
        result.value.then(res=>{
            next(res);
        })
    }

    next();
}

run(gen)

co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行。https://github.com/tj/co

co 函数库可以让你不用编写 Generator 函数的执行器。

var co = require('co');
co(gen);

co 函数库的源码https://github.com/tj/co/blob/master/index.js

实现co框架

function co(gen) {
    return new Promise((resolve, reject) => {
        var fulfilled = (value) => {
            try {
                step(gen.next(value));
            } catch (e) {
                reject(e);
            }
        };
        var rejected = (value) => {
            try {
                step(gen.throw(value));
            } catch (e) {
                reject(e);
            }
        };
        var step = (result) => {
            result.done ? resolve(result.value)
                : Promise.resolve(result.value).then(fulfilled, rejected);
        };

        step((gen = gen()).next());
    });
}  

co(function*(){
    let a = yield $.get('http://v.beihaoyun.com/api/hosp/doctor/list?page=1&pageSize=4&status=1');
    console.log(a)
    let b = yield $.get('http://v.beihaoyun.com/api/article/post/list?page=1&pageSize=4&article_category_id=10');
    console.log(b)
    let c = yield $.get('http://v.beihaoyun.com/api/question/list2?page=1&pageSize=4&top_id=0&add_answer=true');
    console.log(c)
})

参考资料

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部