资讯专栏INFORMATION COLUMN

Genrator浅析

NotFound / 1737人阅读

摘要:通过可以做到按需获取。切出的过程类似将一个值带出协程同时主线程可以在一系列或者操作之后通过的方法与其通信恢复协程执行。对象上部署接口使其具有可遍历性

生成器的主要功能:通过一段程序,持续迭代或枚举出符合某个公式或者算法的有序数列中的元素.

在js中的具体表现形式就是function*。通过generator可以做到按需获取。
怎么理解,比如我们想获取一定数量的fibonacci,可以通过下面这种方式;

function * fibo() {
    let a=0;
    let b=1;
    yield a;
    yield b;

    while (true){
        let next = a+b;
        a=b;
        b=next;
        yield  next;
    }
}
let generator=fibo();
for(let i=0;i<10;i++){
    process.stdout.write(generator.next().value+" ");
}
console.log(".")   //0 1 1 2 3 5 8 13 21 34 .

上面比较特殊的一点就是yield,作用与return类似,但并非退出函数体,而是切出函数运行时。
切出的过程类似将一个值带出协程(coroutine);同时主线程可以在一系列sync或者async操作之后,通过generator的next方法与其通信,恢复协程执行。

随意创建一个generator,通过其原型链查看到generator主要有一下几个方法

generator.next(value) 获取下一次生成器切出状态(第一次执行时为第一个切出状态)

generator.throw(error) 向当前生成器返回执行对象抛出错误,终止生成器运行,除非被异常被捕获

generator[Symbol.iterator] 为生成器提供实现可迭代的方法(通过for-of语句可用)

generator.return 返回给定的值,终结遍历Generator函数

其中用的最多用的是第一个方法。

生成器主要应用场景(现阶段我感觉只有下面两个用处)

同步化的方式表达异步操作,解决金字塔回调问题。

before like this

        //normal version
        function echo(content,cb) {
            cb(null,content);
        }
        function run() {
            echo("hello", (...rest0) => {
                 console.log(rest0[1]+" world");
            });
        }
        run();  //hello world

generator equivalent writing

//thunk version
function echo(content) {
    return cb => {
        cb(null,content);  //generator作为logic主体,主线程执行异步方法
    }
}
function run(genFn) {
    const gen=genFn();
    const next= value =>{
        const ret=gen.next(value);
        if(ret.done)return;
        ret.value((err,val) => {  //async tasks
            if(err) return console.error(err);
            next(val);  //recursion
        });

    }
    next();
}
run(function* () {
    const msg0= yield  echo("hello");
    const msg1= yield  echo(`${msg0} world`);
    console.log(msg1); //hello world
});

说明 我上面这种写法虽然简单,但是很多变种库都有其影子,例如co,koa1 and so on。

对象上部署Iterator接口,使其具有可遍历性

function* setIterator(obj) {
     let keys = Object.keys(obj);
     for (let i=0,len=keys.length; i < len; i++) {
       let key = keys[i];
       yield [key, obj[key]];
     }
   }

   let obj = { name: "gcy", age: "infinity" };

   for (let [key, value] of setIterator(obj)) {
     console.log(key, value);
   }

// name gcy
// age infinity

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86926.html

相关文章

  • 用Promise、Generator、Async函数将异步操作同步化

    摘要:函数最简单,不需要借助其他的执行器即可按照顺序执行。函数执行过程中遇到就会交出执行权限,等到异步操作完成再进行下面的操作,语句返回的是方法的参数。小程序不支持函数,并且同时间最多支持个请求,所以被迫无奈,只能使用来做异步批量调用。 在日常开发的过程中总会遇到一些下一个请求需要上一个请求的响应数据作为参数(或者坑爹的小程序开发只能同时最多请求5个),那么这个时候我们就需要批量地请求一批后...

    jaysun 评论0 收藏0
  • 浅析微信支付:支付验收示例和验收指引

    摘要:本文是浅析微信支付系列文章的第十一篇,主要讲解支付验收示例和验收指引。为保证商户接入质量,提升交易安全及用户体验,微信支付的合作服务商在正式上线交易前,必须先根据本文指引完成验收。 本文是【浅析微信支付】系列文章的第十一篇,主要讲解支付验收示例和验收指引。 浅析微信支付系列已经更新十一篇了哟~,没有看过的朋友们可以看一下。 浅析微信支付:如何使用沙箱环境测试 浅析微信支付:下载对账单...

    Cympros 评论0 收藏0
  • 浅析微信支付:如何使用沙箱环境测试

    摘要:本文是浅析微信支付系列文章的第十篇,主要讲解如何使用沙箱环境来测试微信支付。图为微信支付仿真测试系统后简称仿真系统的简化原理图。沙箱说明微信支付沙箱环境,是提供给微信支付商户的开发者,用于模拟支付及回调通知。 本文是【浅析微信支付】系列文章的第十篇,主要讲解如何使用沙箱环境来测试微信支付。 浅析微信支付系列已经更新十篇了哟~,没有看过的朋友们可以看一下。 浅析微信支付:下载对账单和资...

    骞讳护 评论0 收藏0
  • 浅析微信支付:查询订单和关闭订单

    摘要:本文是浅析微信支付系列文章的第七篇,主要讲解微信商户平台的订单查询和关闭接口的使用。查询订单以下为微信官方的查询订单文档应用场景该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。 本文是【浅析微信支付】系列文章的第七篇,主要讲解微信商户平台的订单查询和关闭接口的使用。 浅析微信支付系列已经更新六篇了哟~,没有看过的朋友们可以看一下哦。 ...

    Dean 评论0 收藏0
  • 浅析微信支付:微信公众号网页授权

    摘要:浅析微信支付微信公众号网页授权本文是浅析微信支付系列文章的第四篇,主要讲解微信支付前如何获取获取网页授权及用户信息获取。浅析微信支付系列已经更新三篇了哟,没有看过的朋友们可以看一下哦。 浅析微信支付:微信公众号网页授权 本文是【浅析微信支付】系列文章的第四篇,主要讲解微信支付前如何获取获取网页授权及用户信息获取。 浅析微信支付系列已经更新三篇了哟~,没有看过的朋友们可以看一下哦。 浅...

    tinyq 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<