大家好,我是进阶学习者。
网站建设哪家好,找创新互联公司!专注于网页设计、网站建设、微信开发、成都小程序开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了丰宁免费建站欢迎大家使用!
常规函数只会返回一个单一值(或者不返回任何值)。
而 Generator 可以按需一个接一个地返回(“yield”)多个值。它们可与 iterable 完美配合使用,从而可以轻松地创建数据流。
要创建一个 generator,需要一个特殊的语法结构:function*,即所谓的 “generator function”。
Generator 函数与常规函数的行为不同。在此类函数被调用时,它不会运行其代码。而是返回一个被称为 “generator object” 的特殊对象,来管理执行流程。
例如,可以创建一个 generator 并获取其第一个产出的(yielded)值:
- function* generateSequence() {
- yield 1;
- yield 2;
- return 3;
- }
- let generator = generateSequence();
- let one = generator.next();
- alert(JSON.stringify(one)); // {value: 1, done: false}
截至目前,只获得了第一个值,现在函数执行处在第二行:
让再次调用 generator.next()。代码恢复执行并返回下一个 yield 的值:
- let two = generator.next();
- alert(JSON.stringify(two)); // {value: 2, done: false}
如果第三次调用 generator.next(),代码将会执行到 return 语句,此时就完成这个函数的执行:
- let three = generator.next();
- alert(JSON.stringify(three)); // {value: 3, done: true}
运行结果:
当你看到 next() 方法,或许你已经猜到了 generator 是 可迭代(iterable)的。(译注:next() 是 iterator 的必要方法)
可以使用 for..of 循环遍历它所有的值:
- function* generateSequence() {
- yield 1;
- yield 2;
- return 3;
- }
- let generator = generateSequence();
- for(let value of generator) {
- alert(value); // 1,然后是 2
- }
运行结果:
注:
上面这个例子会先显示 1,然后是 2,然后就没了。它不会显示 3!
这是因为当 done: true 时,for..of 循环会忽略最后一个 value。因此,如果想要通过 for..of 循环显示所有的结果,必须使用 yield 返回它们:
- function* generateSequence() {
- yield 1;
- yield 2;
- yield 3;
- }
- let generator = generateSequence();
- for(let value of generator) {
- alert(value); // 1,然后是 2,然后是 3
- }
因为 generator 是可迭代的,可以使用 iterator 的所有相关功能。
例如:spread 语法 ...:
- function* generateSequence() {
- yield 1;
- yield 2;
- yield 3;
- }
- let sequence = [0, ...generateSequence()];
- alert(sequence); // 0, 1, 2, 3
运行结果:
Generator 组合(composition)是 generator 的一个特殊功能,它允许透明地(transparently)将 generator 彼此“嵌入(embed)”到一起。
例如,有一个生成数字序列的函数:组合的 generator 的例子:
- function* generateSequence(start, end) {
- for (let i = start; i <= end; i++) yield i;
- }
- function* generatePasswordCodes() {
- // 0..9
- yield* generateSequence(48, 57);
- // A..Z
- yield* generateSequence(65, 90);
- // a..z
- yield* generateSequence(97, 122);
- }
- let str = '';
- for(let code of generatePasswordCodes()) {
- str += String.fromCharCode(code);
- }
- alert(str); // 0..9A..Za..z
运行结果:
上面的例子中观察到的那样,外部代码可能会将一个值传递到 generator,作为 yield 的结果。
但是它也可以在那里发起(抛出)一个 error。这很自然。
因为 error 本身也是一种结果,要向 yield 传递一个 error,应该调用 generator.throw(err)。
在这种情况下,err 将被抛到对应的 yield 所在的那一行。
例:
"2 + 2?" 的 yield 导致了一个 error:
- function* gen() {
- try {
- let result = yield "2 + 2 = ?"; // (1)
- alert("The execution does not reach here, because the exception is thrown above");
- } catch(e) {
- alert(e); // 显示这个 error
- }
- }
- let generator = gen();
- let question = generator.next().value;
- generator.throw(new Error("The answer is not found in my database")); // (2)
运行结果:
本文基于JavaScript基础,介绍了Generator函数 ,重点介绍了如何进行Generator 组合,采用图文结合的方式。采用JavaScript语言,能够更直观的的理解,希望能够帮助读者更好的学习。
欢迎大家积极尝试,有时候看到别人实现起来很简单,但是到自己动手实现的时候,总会有各种各样的问题,切勿眼高手低,勤动手,才可以理解的更加深刻。
代码很简单,希望对你学习有帮助。
本文题目:一文带你搞懂JavaScript的Generator函数
文章起源:http://www.36103.cn/qtweb/news14/25714.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联