咱们通过上篇文章的简单介绍,已经了解到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很像,都是用来解决异步操作相关问题的。废话不多说,咱们在下一篇文章中直接拿来玩,感兴趣的话,可以继续关注我。

generator-yield到底是个啥的更多相关文章

  1. Generator & yield write in sync way

    Generator & yield write in sync way var p = new Promise(function(resolve, reject){ setTimeout(fu ...

  2. Generator yield语法和 co模块

    Generator  yield 语法使用,也叫生成器,实际上就是多个异步按顺序执行 1.下面是一个读取两个文件的例子 const fs = require('fs'); const readFile ...

  3. 异步编程的上下文与操作符--await/async generator/yield

    上下文的保存机制: 1.保存到异步类型中:promise & future & closure & observable: 2.栈帧保存:其它保存机制: 3.保存到服务提供方的 ...

  4. ES Next & Arrow function & Promise & Iterator & Generator yield & Async Await

    ES Next & Arrow function & Promise & Iterator & Generator yield & Async Await co ...

  5. 生成器(generator,yield),next,send

    #生成器 def generator(): for i in range(200): yield '哇哈哈%s' %i g = generator() #调用生成数函数,接受作用 ret = g.__ ...

  6. python3----生成器generator(yield)

    # 列表推导式a = [i for i in range(100) if not(i % 2) and (i % 3)]print(a)# 字典推导式b = {i: i % 2 == 0 for i ...

  7. Python: generator, yield, yield from 详解

    1.Generator Expressions 生成器表达式是用小括号表示的简单生成器标记法: generator_expression ::= "(" expression co ...

  8. JS Generator yield

    function show() { console.log('a') console.log('b') } show() // 普通函数 function *show2() { console.log ...

  9. Python高级语法之:一篇文章了解yield与Generator生成器

    Python高级语法中,由一个yield关键词生成的generator生成器,是精髓中的精髓.它虽然比装饰器.魔法方法更难懂,但是它强大到我们难以想象的地步:小到简单的for loop循环,大到代替多 ...

  10. Python yield 使用浅析

    转载来自: http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ 初学 Python 的开发者经常会发现很多 Pyth ...

随机推荐

  1. Session 和cookie机制详解

    参考: http://blog.csdn.net/fangaoxin/article/details/6952954/ http://blog.csdn.net/hjc1984117/article/ ...

  2. torch7 安装中Missing dependencies for nn:moses >= 1错误解决办法

    Torch7.0安装步骤(默认安装路径是在home下): git clone https://github.com/torch/distro.git ~/torch --recursive cd ~/ ...

  3. 【二叉树的递归】06填充每个节点中的下一个正确的指针【Populating Next Right Pointers in Each Node】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树 struct Tr ...

  4. 洛谷 P4220 & UOJ #347 通道 —— 随机化

    题目:https://www.luogu.org/problemnew/show/P4220 http://uoj.ac/problem/347 先写了一下 n^2 和三棵树一样的情况,n^2 还写了 ...

  5. hdu 1506 单调栈问题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1506 题目的意思其实就是要找到一个尽可能大的矩形来完全覆盖这个矩形下的所有柱子,只能覆盖柱子,不能留空 ...

  6. navicat自动备份

    http://blog.csdn.net/eastmount/article/details/70239244

  7. union联合体学习

    union,中文名“联合体.共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量. 不过区别也挺明显: 结构体(st ...

  8. java处理中日文字符串的乱码问题

    ——杂言:前段时间在处理音频预览问题,详见关于audiojs的研究.期间,将远端的音频下载并缓存在本地过程中,涉及到java.io.*的几个操作,发生一些乱码问题. 我以前的处理是将本地的编码转换为U ...

  9. new/delete 和malloc/free 的区别

    new/delete 和malloc/free 的区别 一.基本概念malloc/free:1.函数原型及说明:      void *malloc(long NumBytes):该函数分配了NumB ...

  10. 【总结整理】http-https

    上面这种加密消息的方式就是对称加密,你知道如何加密,也知道如何解码.然后李雷跟韩梅梅用的字母表偏移的加密方法叫 Caesar cipher, 凯撒加密.现实世界中用的加密算法会更复杂,但是基本原理相同 ...