generator的基本使用及co库的原理

通常ajax请求都会用到异步调用问题,为了保证调用顺序的正确性,一般会用到callback,后来出现了promise的解决方案。
在异步编程中,还有一种解决方案,那就是generator生成器函数,这个函数会返回一个迭代器。

特点:函数声明只是多了个*号来表示这是一个生成器函数,并且一般可以在函数内看到yield关键字。
原理:它会将一个函数分为若干个小函数,并且返回一个迭代器,通过调用迭代的next方法(移动指针),内部遍历值、状态,保持正确的执行顺序。每次调用next方法,都会向下执行一步。
用法:
1.先产出,下一个next负责传值,然后接收新值。
2.yield后面跟着的是value值(产出值)。 yield等号前面的 是我们当前调用next传进来的 值。没有等号代表不接收新值。 注意点:迭代器的第一个next执行,传值是无效的。
function *read(){
    console.log(1);
    var content1 = yield 'qs';
    console.log(content1);
    var content2 = yield '9';![图片描述][1]
    console.log(content2);
    return content2;
}
var it = read();
var a = it.next() //输出 1  a:{value:'qs',done:false}
var b = it.next('hello')//输出hello  b:{value:'9',done:false}
var c = it.next('generator')//输出generator  c:{value:'generator',done:true}
var d = it.next('123')//输出generator  c:{value:undefined,done:true}
console.log(a,b,c,d)

具体的执行步骤,见图分解图片描述

产出的值 是一个object,包含两个key :value 和 done value
表示产出的值,done表示执行状态(迭代器是否执行完成,全部遍历一遍) 当done
为true时表示遍历完成。之后再次执行next,就没有产出了,所以value为undefined,done仍旧是true;

用处:generator一般和promise结合一起用

let fs = require('fs');
let blueBird =  require('bluebird');
let read2 = blueBird.promisify(fs.readFile);
function *r(){
    let content1 = yield read2('./1.txt','utf8');
    let content2 = yield read2(content1,'utf8');
    return content2
}
let it2 = r();
it2.next().value.then(res=>{
   it2.next(res).value.then(res=>{
        console.log(res);
        console.log(it2.next(res));//需要给content2赋值,然后产出{ value: '大大大', done: true }
    })
});

为了更好的结合promise使用,出现了co库。
co库的作用就是:把一个生成器函数的迭代器,最后一步执行完毕后,然后统一执行一个成功回调
安装:npm install co --save


let co = require('co');
function *r2(){
    let content1 = yield read2('./1.txt','utf8');
    let content2 = yield read2(content1,'utf8');
    return content2
}
co(r2).then(function(res){console.log(res,11111111111111)});

co库实现原理,就是利用产出值的done的状态,去判断是否需要再次递归执行next方法。

function co(it){
    return new Promise(function(resolve,reject){
        function next(data){
            let {value,done}= it.next(data);
            if(!done){
                value.then(res=>{
                    next(res);
                },reject)
            }else{
                resolve(value)
            }
        }
        next();
    })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值