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

 2023-09-10 阅读 17 评论 0

摘要:yield是什么 yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性ÿ

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()使用

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

 

生成器产生值

闭包实现

 //闭包实现值与值之间联系的输出   可能会资源泄露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

java随机生成汉字?

其中[...]语法被称为计算机属性名。涉及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;}}

php生成唯一id、注意: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异常处理总结)

 

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/35718.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息