• generator-yield到底是个啥


    咱们通过上篇文章的简单介绍,已经了解到yield是放弃执行,放弃现在继续执行的权利,把权利让给别人,什么时候想继续执行的时候,再调一次就好。接下来咱们说两件事,就是yield是一个很有意思的东西,它可以传参,也可以有返回值。(提醒:接下来的东西略微有点难懂,大家不要过于纠结和较真,后面应用的时候,很多东西就自然通顺了)
     
    一、yield可以传参
    先来一个函数

        function *show() {
          alert('a');
    
          let a = yield;
          alert(a);
    
          alert('b');
        }
    
        let gen = show();
    
        gen.next(12);
        gen.next(5);


    通过函数我们可以看到,定义a接收了yield传进来的参数,现在请大家和我玩个游戏,猜猜看a是几
    好了,不卖关子了,咱们执一下看看


    那么现在反过来就有一个问题了,可能有些人会说,等会,我有点看不明白了,我怎么觉得应该是12呢,怎么回事呢?
    好,简答的说一说为什么是5,这个实际上来说是yield里面特别好玩的一件事,大家允许我用一个小小的方法(用一张图来说明)


    从上面的图上,我们可以看到画红框的地方,执行的是我用红笔圈起来的这部分代码,画绿框的地方,执行的是用绿笔圈起来的代码
    我们把它简答的看做两个过程,第一个过程传进去的参数是12,第二个过程传递进去的参数是5,所以我们的a接收到的是我们第二个过程里传进去的5,没问题吧,当然还是那句话,别较真,认真你就输了,大家都懂的哈
     
    那么所以通过yield传参的时候,第一个next是废的,传什么都不好使,传什么都白传,这个时候大家可能会问了,那我想给第一个过程传参,该怎么办呢?你说怎么办,不就是我们过去的传参方法嘛,我们传一个num1,一个num2,然后接收一下,咱试试哈

        function *show(num1, num2) {
          alert(`${num1}, ${num2}`);
          alert('a');
    
          let a = yield;
          alert(a);
    
          alert('b');
        }
    
        let gen = show(99, 88);
    
        gen.next(12);
        gen.next(5);


    这样运行的话,可以正常接收我们传进来的参数


    而通过这个过程,我们可以看到,第一个next对于传参来说,是废的,没办法给yield传参的,想给第一个过程传递参数,就得像正常函数一样,通过函数(参数)的形式来
     
    二、yield可以返回
    咱们刚刚说了yield的第一个功能是可以往里面传东西,下面我们说一说yield的另一个功能,可以往外吐东西(返回)
     
    咱们在上面把一个大的generator函数划分为几个过程,通过yield来分割这几个过程,我们可以理解为中间结果
    举个最简单的例子,就像我做菜一样,当然我这人不会做菜,连锅都能糊了,可好玩了,有时间再和大家慢慢扯哈


    就拿做菜来说,我们可以分为几个步骤:洗菜、切菜、炒菜
    我们可以认为,在最开始输入了刚买回来的菜,也相当于我们函数的参数,接下来的每一步都有一个半成品(刚买回来的菜),它也就相当于我们下一步的输入,最后变成一盘炒好的菜。说白了,在这个函数里,每一步都会有一个中间结果,也算是中间的输入。

    从第一步的yield可以传参到第二步的yield有个中间结果,下面我们看一看yield是如何返回的

        function *show() {
          alert('a');
    
          yield 12;
    
          alert('b');
    
        }
    
        let gen = show();
    
        let res1 = gen.next();
        console.log(res1);    //{value: 12, done: false}
    
        let res2 = gen.next();
        console.log(res2);    //{value: undefined, done: true}


    咱们还是和刚才一样,定义一个generator函数,定义两个过程,将next函数的返回值打印出来之后可以看到,第一个过程中返回了
    {value: 12, done: false},第二个过程返回了{value: undefined, done: true},在第一个过程里,value是12,done是false,done是完成的意思,因为第一个过程并不是函数结束,所以返回的是false,而第二个返回值中,value为什么是undefined呢?
    原因很简单,咱们在上面的切菜图上说的很明白了,这个阶段是咱们函数的最后一道工序,最后一道工序就没有yield了,所以也就没有返回值了,想返回东西的话,就只能用return来返回。

    请允许我用一个更俗的例子来把这事说的更清楚。
     
    三、yield到底是个啥



    咱们用伪代码定义了一个generator函数,咱名字就叫炒菜,最初的参数是刚从菜市场买回来的菜,第一步完成洗菜的过程,然后通过yield把洗好的菜传递给下一个过程,下一个人拿到干净的菜之后把它切成块,切成丝,再通过yield传给下一个人,然后下一个人拿到切好的菜之后,就可以炒了,最后我们得到熟的菜,把它return出去。下面咱们画一画,帮助大家更好的理解


     
    首先蓝色框里画的是第一个过程,红色框是第二个过程,绿色框是第三个过程,而中间的yield就相当于隔在他们中间的“墙”,“墙”之前是一个过程,之后是另一个过程。在过程一的输入是(菜市场买回来的菜),做了一些工作之后,把洗好的菜(中间结果)返回出去,在“墙”的那边,得到的是我们返回的干净的菜,然后咣咣咣一顿切之后,得到了切好的菜(中间结果),有了中间结果之后,在“墙”的那一边有人得到了我们的中间结果,然后拿去炒,得到熟的菜,最终的结果return出去。总的来说,最初的东西走参数,最终的结果走return,其实generator咱要这么说的话,也不难,就是中间步骤可以返回出去,那边怎么着怎么着,反正就这点事。

    相信通过上面有些神经病的讲解之后,相信大家应该比较彻底的了理解了generator以及它的yield,还是那句话,较真你就输了。
     
    接下来呢,咱们要干件事了,既然明白了,既然理解了,接下来趁热打铁,咱们用一用它,中国有句古话“光说不练....”,嗯,大家都懂,我就不多说了,咱们来用一用它,看看它能干啥,generator其实在很大程度上和Promise很像,都是用来解决异步操作相关问题的。废话不多说,咱们在下一篇文章中直接拿来玩,感兴趣的话,可以继续关注我。

  • 相关阅读:
    form表单提交方式
    docker overlay2 目录下文件夹占用空间过大
    基本操作:vscode快捷键
    基本操作:vscodegit使用和命令
    关闭win10“快速启动”功能
    在CentOS 7.4下配置VNC Server服务
    golang 百分比抽奖几率
    对新闻客户端APP的性能优化实战
    性能优化专题 OOM 与 内存优化
    centos 安装谷歌浏览器和selenium环境 李刚
  • 原文地址:https://www.cnblogs.com/hizhy/p/10999646.html
Copyright © 2020-2023  润新知