Mr.J -- yield关键字生成器产生值
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()函数及参数
在js中,虽然借鉴了python的函数,但是也进行了自己的改造,由于没有send()函数,所以无法直接传递yield的值。
next()可以带一个参数,该参数会被认为是上一个yield整体的返回值,稍后将在代码中展示。
在某种程度上,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关键字生成器产生值相关推荐
- python yield关键字全面解析
你是否曾因处理的数据集过大而内存溢出?你是否曾因为处理各种复杂的函数状态而烦恼?It does help! 本文聚焦yield generator, 帮助你解锁python进阶技法,写出更优雅的程序! ...
- Python(IT峰)笔记07-数据类型详解-元祖的定义与操作,元祖推导式,元祖生成器,yield关键字,字典及定义,字典所支持的操作,zip研所函数,dict转型,字典函数,集合,冰冻集合,集合推导
1.元祖的定义 一组有序数据的组合,元祖一旦定义不可修改,是不可变数据类型 定义空元祖 变量=() 变量=tuple() 变量=(内容1,内容2,内容3,--)直接赋值 特列:变量=内容1,内容2,内 ...
- python生成器yield原理_生成器yield关键字详解
鉴于yield关键字的原理大家理解的都不是很深刻,今天我们主要就这一课题进行探讨. 生成器可以用什么方式得到? 方法一: 利用推导式的方式得到生成器# 列表推导式 list1 = [i for i i ...
- Python 生成器 和 yield 关键字
Python 中 yield 的作用:http://youchen.me/2017/02/10/Python-What-does-yield-do/# Python 生成器详解:http://codi ...
- Python生成器实现及yield关键字
Python生成器实现及yield关键字 我在另一篇文章中介绍了Python迭代器,https://blog.csdn.net/weixin_43790276/article/details/9034 ...
- Python中的yield关键字及表达式、生成器、生成器迭代器、生成器表达式详解
文章目录 1. yield关键字及表达式.生成器.生成器迭代器.生成器表达式 1.1 yield关键字及表达式(yield expression) 1.1.1 yield关键字 1.1.2 yield ...
- C#中使用的yield关键字是什么?
在" 如何仅显示IList <>的片段"问题中,答案之一具有以下代码片段: IEnumerable<object> FilteredList() {fore ...
- “ yield”关键字有什么作用?
Python中yield关键字的用途是什么? 它有什么作用? 例如,我试图理解这段代码1 : def _get_child_candidates(self, distance, min_dist, m ...
- python function if yield_Python中的yield关键字
Python中的yield关键字 这是stackoverflow上一个关于yield关键字的问题以及它被推荐次数最高的一个答案 问题: Python中的yield关键字是什么?它是用来做什么的? 例如 ...
最新文章
- idea 使用 git 教程
- 表达不同与构建不同: 对计算机的唯一真正的要求 (TrustNo.1 ) -- 待修改!!!...
- “无路之门”,一款VR恐怖冒险游戏
- JS解析XML文件和XML字符串
- K8S部署工具:KubeOperator集群导入
- gradle镜像配置:使用阿里云仓库服务的代理仓库地址代替jcenter()、mavenCentral()及google()
- 开漏(open drain)和开集(open collector)
- .NET FM的未来计划
- chartjs更新数据 vue_vue.js - 在vue中 怎么更改chart图表的文字大小
- react入门jsx
- java使用ssh下载git代码_使用Java用户名和密码在ssh上克隆git存储库
- 注册测绘师划出后的分析与思考
- java windows 中文乱码问题_JAVA中文乱码之解决方案
- 【演化(进化)算法】遗传算法原理及python实现
- bzoj 4318 osu 【三次方问题】【dp】
- WeUI实现登录页面
- python大学课程实验六_Python程序设计实验六:函数
- UVA1665 Islands (并查集)
- 【数据恢复】【傲梅分区助手】
- Python turtle画图库画姓名实例(Python入门)
热门文章
- 如何用xml 描述目录结构_如何用英语描述人物外表
- 【OpenCV】OpenCV实战从入门到精通之 -- 图像对比度、亮度值调整
- 总结 | 深度学习PyTorch神经网络箱使用
- 《Python编程从入门到实践》记录之字典嵌套
- 小白来学C语言之数组与指针
- 深度学习(四十一)cuda8.0+ubuntu16.04+theano、caffe、tensorflow环境搭建
- 基于聚类的“图像分割”(python)
- PID参数整定法(1)
- linux 内核模块开发,linux内核模块开发(示例代码)
- 8能达到go速度吗 php_相同逻辑的php与golang代码效率对比,最好语言落谁家…