yield是什么

  • yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。
  • yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性,value和done,分别代表返回值和是否完成。
  • yield无法单独工作,需要配合generator(生成器)的其他函数,如next,懒汉式操作,展现强大的主动控制特性。
  • 如果你看到某个函数中有yield,说明这个函数已经是个生成器了
  • yield可以用来加强控制,懒汉式加载
  • 调用函数指针和调用生成器是两码事,在下面的demo中会发现这一问题。
  • 需要next()函数配合使用,每次调用返回两个值:分别是value和done,代表迭代结果和是否完成
  • 函数next()是个迭代器对象,传参可以缺省,默认调用函数。

简单的小demo

function *foo(x){var y = x*(yield "Hello");return y;}var it = foo(6);//不传任何东西var res = it.next();console.log(res.value);//等待的yield传入7var res = it.next(7);console.log(res.value);   

yield说明

  • yield并不能直接生产值,而是产生一个等待输出的函数
  • 除IE外,其他所有浏览器均可兼容(包括win10 的Edge)
  • 某个函数包含了yield,意味着这个函数已经是一个Generator
  • 如果yield在其他表达式中,需要用()单独括起来
  • yield表达式本身没有返回值,或者说总是返回undefined(由next返回)
  • next()可无限调用,但既定循环完成之后总是返回undefined

使用next()

function* foo(x) {var x = yield 2;z++;var y = yield (x * z);console.log(x, y, z);}var z = 1;var it1 = foo();var it2 = foo();//从yield 2 获取值 2var val1 = it1.next().value;var val2 = it2.next().value;console.log(val1);console.log(val2);val1 = it1.next(val2 * 10).value;           //x=2*10 z=2 y=40 val1=40   x=20 y=40val2 = it2.next(val1 * 5).value;            // 40*5  200*3  val2=600       x=200 y=600console.log(val1);console.log(val2);console.log(it1.next(val2 / 2));                //600/2 y=300console.log(it2.next(val1 / 4));                //40/4 y=10

next()函数及参数

  1. 在js中,虽然借鉴了python的函数,但是也进行了自己的改造,由于没有send()函数,所以无法直接传递yield的值。

  2. next()可以带一个参数,该参数会被认为是上一个yield整体的返回值,稍后将在代码中展示。

  3. 在某种程度上,next()可以直接当做send()使用

它的意义在于,可以在不同阶段从外部直接向内部注入不同的值来调整函数的行为(这一点是其他循环很难做到的,或要付出较大的代价才可以做到)

生成器产生值

闭包实现

 //闭包实现值与值之间联系的输出   可能会资源泄露var something = (function(){var nextVal;return function(){if(nextVal === undefined){nextVal = 1;}else{nextVal = (3*nextVal) + 6;}console.log(nextVal);    };})();something();something();something();something();

数字序列生成器

 // 数字序列生成器实现迭代器接口var something = (function(){var nextVal;return {[Symbol.iterator]:function(){return this;},next:function(){if(nextVal === undefined){nextVal=1;}else{nextVal = (3*nextVal) + 6;}return {done:false,value:nextVal};}};})();console.log( something.next().value);         //1console.log( something.next().value);         //9console.log( something.next().value);         //33console.log( something.next().value);         //105

其中[...]语法被称为计算机属性名。涉及ES6特性。可以在文档中自己查阅(ES6文档查看)

ES6实现迭代器

 //ES6通过原生循环语法自动迭代标准迭代器for(var v of something){console.log(v);if(v>500){break;}}//1 9 33 105 321 969

上面是ES6通过原生循环语法自动迭代标准迭代器。同样我们可以手动进行迭代器进行循环

 for(var ret;(ret = something.next()) && !ret.done;){console.log(ret.value);if(ret.value>500){break;}}//1 9 33 105 321 969

生产器迭代器

function* something() {var nextVal;//生成器在每次迭代中暂停,通过yield返回主程序或事件循环队列中  使用while不害怕死循环while (true) {if (nextVal === undefined) {nextVal = 1;} else {nextVal = (3 * nextVal) + 6;}yield nextVal;};};//调用something()迭代器for (var v of something()) {console.log(v);if (v > 500) {break;}}

注意:1.这里的something时生成器,不是iterable,需要调用something()构造for...of循环迭代

2.somehitng调用产生迭代器,for...of需要iterable.生产器的迭代器也有一个Symbol.iterator函数,和之前定义的iterable                    something一样。生成器的迭代器也是一个iterable!

停止生成器

//在内部通过try finally 捕捉 自动结束程序function* something() {try {var nextVal;while (true) {if (nextVal === undefined) {nextVal = 1;} else {nextVal = (3 * nextVal) + 6;}yield nextVal;}}finally {console.log("Cleaning up!");}};//手工中止生成器 var it = something();for (var v of it) {console.log(v);if (v > 500) {console.log(//完成生成器的迭代器it.return("Hello world").value);//不需要break}}

1.通过捕捉异常进行生成器中止。

2.外部进行手工中止。

不会异常处理,异常处理可以看我之前的文章(Mr.J--Java异常处理总结)

Mr.J -- yield关键字生成器产生值相关推荐

  1. python yield关键字全面解析

    你是否曾因处理的数据集过大而内存溢出?你是否曾因为处理各种复杂的函数状态而烦恼?It does help! 本文聚焦yield generator, 帮助你解锁python进阶技法,写出更优雅的程序! ...

  2. Python(IT峰)笔记07-数据类型详解-元祖的定义与操作,元祖推导式,元祖生成器,yield关键字,字典及定义,字典所支持的操作,zip研所函数,dict转型,字典函数,集合,冰冻集合,集合推导

    1.元祖的定义 一组有序数据的组合,元祖一旦定义不可修改,是不可变数据类型 定义空元祖 变量=() 变量=tuple() 变量=(内容1,内容2,内容3,--)直接赋值 特列:变量=内容1,内容2,内 ...

  3. python生成器yield原理_生成器yield关键字详解

    鉴于yield关键字的原理大家理解的都不是很深刻,今天我们主要就这一课题进行探讨. 生成器可以用什么方式得到? 方法一: 利用推导式的方式得到生成器# 列表推导式 list1 = [i for i i ...

  4. Python 生成器 和 yield 关键字

    Python 中 yield 的作用:http://youchen.me/2017/02/10/Python-What-does-yield-do/# Python 生成器详解:http://codi ...

  5. Python生成器实现及yield关键字

    Python生成器实现及yield关键字 我在另一篇文章中介绍了Python迭代器,https://blog.csdn.net/weixin_43790276/article/details/9034 ...

  6. Python中的yield关键字及表达式、生成器、生成器迭代器、生成器表达式详解

    文章目录 1. yield关键字及表达式.生成器.生成器迭代器.生成器表达式 1.1 yield关键字及表达式(yield expression) 1.1.1 yield关键字 1.1.2 yield ...

  7. C#中使用的yield关键字是什么?

    在" 如何仅显示IList <>的片段"问题中,答案之一具有以下代码片段: IEnumerable<object> FilteredList() {fore ...

  8. “ yield”关键字有什么作用?

    Python中yield关键字的用途是什么? 它有什么作用? 例如,我试图理解这段代码1 : def _get_child_candidates(self, distance, min_dist, m ...

  9. python function if yield_Python中的yield关键字

    Python中的yield关键字 这是stackoverflow上一个关于yield关键字的问题以及它被推荐次数最高的一个答案 问题: Python中的yield关键字是什么?它是用来做什么的? 例如 ...

最新文章

  1. idea 使用 git 教程
  2. 表达不同与构建不同: 对计算机的唯一真正的要求 (TrustNo.1 ) -- 待修改!!!...
  3. “无路之门”,一款VR恐怖冒险游戏
  4. JS解析XML文件和XML字符串
  5. K8S部署工具:KubeOperator集群导入
  6. gradle镜像配置:使用阿里云仓库服务的代理仓库地址代替jcenter()、mavenCentral()及google()
  7. 开漏(open drain)和开集(open collector)
  8. .NET FM的未来计划
  9. chartjs更新数据 vue_vue.js - 在vue中 怎么更改chart图表的文字大小
  10. react入门jsx
  11. java使用ssh下载git代码_使用Java用户名和密码在ssh上克隆git存储库
  12. 注册测绘师划出后的分析与思考
  13. java windows 中文乱码问题_JAVA中文乱码之解决方案
  14. 【演化(进化)算法】遗传算法原理及python实现
  15. bzoj 4318 osu 【三次方问题】【dp】
  16. WeUI实现登录页面
  17. python大学课程实验六_Python程序设计实验六:函数
  18. UVA1665 Islands (并查集)
  19. 【数据恢复】【傲梅分区助手】
  20. Python turtle画图库画姓名实例(Python入门)

热门文章

  1. 如何用xml 描述目录结构_如何用英语描述人物外表
  2. 【OpenCV】OpenCV实战从入门到精通之 -- 图像对比度、亮度值调整
  3. 总结 | 深度学习PyTorch神经网络箱使用
  4. 《Python编程从入门到实践》记录之字典嵌套
  5. 小白来学C语言之数组与指针
  6. 深度学习(四十一)cuda8.0+ubuntu16.04+theano、caffe、tensorflow环境搭建
  7. 基于聚类的“图像分割”(python)
  8. PID参数整定法(1)
  9. linux 内核模块开发,linux内核模块开发(示例代码)
  10. 8能达到go速度吗 php_相同逻辑的php与golang代码效率对比,最好语言落谁家…