文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

一文带你搞懂JavaScript的Generator函数

2024-11-28 13:53

关注

而 Generator 可以按需一个接一个地返回(“yield”)多个值。它们可与 iterable 完美配合使用,从而可以轻松地创建数据流。

二、Generator 函数

要创建一个 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}

运行结果:

三、Generator 是可迭代的

当你看到 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
}

运行结果:

for..of 写法是不是看起来比 .next().value 优雅多了?

注:

上面这个例子会先显示 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 组合

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.throw

上面的例子中观察到的那样,外部代码可能会将一个值传递到 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语言,能够更直观的的理解,希望能够帮助读者更好的学习。

欢迎大家积极尝试,有时候看到别人实现起来很简单,但是到自己动手实现的时候,总会有各种各样的问题,切勿眼高手低,勤动手,才可以理解的更加深刻。

代码很简单,希望对你学习有帮助。

来源:前端进阶学习交流内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯