”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 了解 JavaScript 生成器:强大的代码流控制工具

了解 JavaScript 生成器:强大的代码流控制工具

发布于2024-11-08
浏览:706

Razumevanje JavaScript Generatora: Moćan Alat za Kontrolu Toka Koda

生成器是 JavaScript 中最强大的功能之一,它允许我们编写可以根据需要暂停和恢复的代码。与一次执行所有代码的常规函数​​不同,生成器使用延迟执行,增量返回值,从而更容易处理数据序列、迭代或长时间运行的进程。

发电机如何工作?

在JavaScript中,生成器是使用function*关键字定义的,并与yield关键字结合,允许部分执行函数。每次我们调用生成器函数时,它不会立即执行,而是返回一个允许受控执行的迭代器。

例子:

const id = (function* () {
    let i = 1;
    while (true) {
        yield i;
        i  = 1;
    }
})();

在此示例中,函数生成器返回无限的数字序列,其中每个数字仅在需要时生成并返回。

yield 有什么作用?

yield 关键字停止生成器的执行并将值返回给外界。在下一个函数调用(使用 next())时,生成器从上次停止的地方继续。

调用生成器是什么样的:

console.log(id.next().value); // 1
console.log(id.next().value); // 2
console.log(id.next().value); // 3

每次调用 next() 都会返回数组的下一个值,并在下一个yield 时暂停函数。

发电机的优点

  • 懒惰:
    生成器不会立即执行所有内容,而是仅在需要时才生成值。这非常适合处理无限序列或大型数据数组。

  • 流量控制:
    暂停和恢复功能的可能性可以更好地控制长时间运行的进程。

  • 效率:
    生成器不是将所有值存储在内存中,而是一次返回一个,这减少了内存消耗。

发电机的缺点

虽然生成器很有用,但它们有几个潜在的问题:

  • 复杂流控制:
    暂停和恢复会使代码更难理解和调试,尤其是在复杂的场景中。

  • 表现:
    在某些情况下,暂停和恢复代码可能会带来额外的开销,从而降低效率。

  • 有限的:
    每次调用返回一个值,如果需要一次访问大量数据,这可能会效率低下。

  • 兼容性:
    生成器是 ECMAScript 2015 (ES6) 标准的一部分,因此如果没有像 Babel 这样的附加工具,较旧的浏览器可能不支持它们。

替代方法

如果生成器引入太多复杂性,您可以考虑替代方案:

带回调的递归函数:

function generateID(callback, start = 1) {
    callback(start);
    setTimeout(() => generateID(callback, start   1), 0);
}
  • 优点:
    更容易的流程控制:虽然使用了递归,但在控制程序流程方面,函数的可读性和清晰性更高。
    异步执行:使用setTimeout可以实现异步操作,这有助于保持性能。

  • 缺点:
    递归开销:对于非常大量的迭代,可能会出现递归问题(堆栈溢出)。

循环:
对于较小的数组,生成预定数量的值的简单循环可能是更有效的选择。

function generateIDs(limit) {
    const ids = [];
    for (let i = 1; i 



  • 优点:
    实现简单:该方案简单易懂,且没有流控问题。
    快速生成:一次性生成所有值,可以以更少的迭代次数提高效率。

  • 缺点:
    内存消耗:所有值都存储在内存中,这对于大型数组可能会出现问题。
    不偷懒:所有 ID 都是预先生成的,如果您不需要全部 ID,效率可能会很低。

迭代器:
通过 .next() 方法返回可迭代值的对象,类似于生成器,但具有更多控制权。

function createIDIterator() {
    let i = 1;
    return {
        next() {
            return { value: i  , done: false };
        }
    };
}

const idIterator = createIDIterator();

console.log(idIterator.next().value); // 1
console.log(idIterator.next().value); // 2
console.log(idIterator.next().value); // 3
  • 优点:
    流程控制:与生成器具有类似的功能,但执行更加线性。
    更简单的代码:没有收益,这可以使代码更容易理解。

  • 缺点:
    没有自动暂停:您必须手动管理迭代,这在某些情况下可能会很不方便。

使用 async/await 异步生成
如果 ID 是异步生成的,则可以将 async/await 与返回 Promise 的函数一起使用。

async function generateID(start = 1) {
    let i = start;
    while (true) {
        await new Promise((resolve) => setTimeout(resolve, 0));
        console.log(i  );
    }
}

generateID(); 
  • 优点:
    异步执行:高效处理长时间运行的操作,而不阻塞主执行流程。
    现代语法:async/await 是一种更现代、更直观的异步代码处理方式。

  • 缺点:
    不适合同步代码:如果需要同步生成,这个解决方案并不理想。

结论

生成器是处理大量无限数据数组以及需要暂停和恢复进程的应用程序中的流量控制的绝佳工具。然而,它们的复杂性和潜在的性能问题意味着它们应该谨慎使用。根据应用程序的要求,迭代、递归或异步代码等替代解决方案可能更合适。

版本声明 本文转载于:https://dev.to/jelena_petkovic/razumevanje-javascript-generatora-mocan-alat-za-kontrolu-toka-koda-2hpo?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • Miva 的日子:第 15 天
    Miva 的日子:第 15 天
    这是 100 天 Miva 编码挑战中的第 15 天,虽然时间过得很快,但它帮助我极大地提高了我的 HTML、CSS 和 JavaScript 技能。 今天,我学习了JavaScript中的两个概念。显示对象属性和 JavaScript 事件。它们对于添加数据以及保持网页的响应性和交互性非常重要。 ...
    编程 发布于2024-11-08
  • 将 JavaScript 转换为 TypeScript 的多年经验:我的关怀意见
    将 JavaScript 转换为 TypeScript 的多年经验:我的关怀意见
    I started my JS career in 2015, spent a year working exclusively with it, and then transitioned to TypeScript. I’d love to say 'And never looked back ...
    编程 发布于2024-11-08
  • x86 汇编中的“锁定”指令是否无限期地保留总线?
    x86 汇编中的“锁定”指令是否无限期地保留总线?
    理解x86汇编中的“Lock”指令x86汇编中的“lock”指令是一个前缀,它强制后续指令对总线的独占所有权。这可确保 CPU 在该指令的持续时间内完全控制高速缓存行。停用总线锁定与通常的理解相反,“lock”前缀不会导致 CPU 锁定无限期的公交车。执行后续指令后,锁会被释放。这允许 CPU 仅在...
    编程 发布于2024-11-08
  • Top itemmap Scraper 你应该知道的 4
    Top itemmap Scraper 你应该知道的 4
    有时需要组织并包含在新网站设计中的信息量可能会令人难以承受,从而使任务变得更加困难。站点地图是一个有用的规划工具,可以帮助组织和简化网站上需要的材料并删除任何不需要的页面。此外,精心设计的站点地图可为访问者提供积极的体验,从而提高转化率。 多年来,最好的网页设计方法一直包括站点地图;因此,它们并不是...
    编程 发布于2024-11-08
  • 如何在 Web 浏览器中跟踪 XMLHttpRequest 的进度更新?
    如何在 Web 浏览器中跟踪 XMLHttpRequest 的进度更新?
    获取 XMLHttpRequest 的进度更新Web 浏览器为客户端-服务器数据交换提供 XMLHttpRequest (XHR) 对象。虽然标准 XHR API 缺乏固有的进度跟踪功能,但有一些方法可以监控数据传输的进度。上传字节数:XHR 公开 xhr.upload。 onprogress 事件...
    编程 发布于2024-11-08
  • 如何在 JavaScript 中向回调函数传递参数?
    如何在 JavaScript 中向回调函数传递参数?
    在 JavaScript 中向回调函数传递参数在 JavaScript 中,回调函数通常用于在某个事件发生后执行特定任务。在定义这些函数时,通常需要向它们传递相关数据或参数。传递参数的一种简单方法是在调用回调函数时将它们显式设置为实参。例如:function tryMe(param1, param2...
    编程 发布于2024-11-08
  • 与 Jira 和 LLM 的互动项目报告
    与 Jira 和 LLM 的互动项目报告
    For all projects I worked on, I used some sort of project management system where project scope was defined as a list of tasks (tickets), and progress...
    编程 发布于2024-11-08
  • 如何在 PHP 中对不同格式的日期数组进行排序?
    如何在 PHP 中对不同格式的日期数组进行排序?
    PHP 日期数组排序在 PHP 中对日期数组进行排序可能很棘手,特别是当日期不是标准化格式时。In根据您的具体情况,您有不同格式的日期数组,例如“11-01-2012”和“01-01-2014”。使用 asort 函数(按升序对数组进行排序)在这种情况下不起作用,因为它将每个日期视为字符串并忽略年-...
    编程 发布于2024-11-08
  • 机器学习中的 C++:逃离 Python 和 GIL
    机器学习中的 C++:逃离 Python 和 GIL
    介绍 当 Python 的全局解释器锁 (GIL) 成为需要高并发或原始性能的机器学习应用程序的瓶颈时,C 提供了一个引人注目的替代方案。这篇博文探讨了如何利用 C 语言进行 ML,重点关注性能、并发性以及与 Python 的集成。 阅读完整的博客! ...
    编程 发布于2024-11-08
  • 如何在 PHP 中将 UTF-8 字符转换为 ISO-8859-1 并返回?
    如何在 PHP 中将 UTF-8 字符转换为 ISO-8859-1 并返回?
    将 UTF-8 字符转换为 ISO-88591 并返回 PHP当使用使用不同编码的多个脚本时,需要在字符集之间进行转换。其中一种转换涉及将 UTF-8 字符转换为 ISO-88591,反之亦然。尽管存在 utf_encode() 和 _decode(),但将 UTF-8 直接转换为 ISO-8859...
    编程 发布于2024-11-08
  • 以下是一些标题选项,使用问题格式,重点关注文章中提出的挑战和解决方案:

选项 1(直接且简洁):
* 如何避免 Angul 中的模板标签冲突
    以下是一些标题选项,使用问题格式,重点关注文章中提出的挑战和解决方案: 选项 1(直接且简洁): * 如何避免 Angul 中的模板标签冲突
    为 AngularJS 和 Django 定制模板标签由于模板标签冲突,将 AngularJS 与 Django 集成可能会带来挑战,两者都使用{{}}。为了克服这个问题,需要调整 AngularJS 或 Django 的模板标签语法。AngularJS 模板标签定制:在 AngularJS 1.0...
    编程 发布于2024-11-08
  • 每个开发人员都应该了解的高级 JavaScript 概念
    每个开发人员都应该了解的高级 JavaScript 概念
    JavaScript 是许多开发人员日常使用的语言,但其生态系统中存在许多隐藏的瑰宝,即使是经验丰富的开发人员也可能不熟悉。本文探讨了一些鲜为人知的 JavaScript 概念,它们可以显着提高您的编程技能。我们将介绍 代理、符号、生成器等概念,通过示例演示每个概念并解决问题以说明其强大功能。 最...
    编程 发布于2024-11-08
  • 直接用mysqli_函数替换mysql_函数会带来挑战吗?
    直接用mysqli_函数替换mysql_函数会带来挑战吗?
    盲目用 mysqli_ 替换 mysql_ 函数会导致问题吗?将代码库更新到 PHP 7 需要将已弃用的 mysql_ 函数替换为 mysqli_ 对应函数。然而,一个常见的误解是您可以直接进行全面替换。答案:不,事情没那么简单虽然函数名称可能会出现类似地,与 mysql_ 相比,mysqli_ 函...
    编程 发布于2024-11-08
  • 为什么 `malloc()` 在 C++ 中会导致“无效转换”错误?
    为什么 `malloc()` 在 C++ 中会导致“无效转换”错误?
    Malloc 分配问题:了解“无效转换”错误提供的代码在尝试使用 malloc 分配内存时引入了一个常见问题( )。该错误源于将 malloc() 的返回值直接分配给 char 指针而没有进行正确的转换。malloc() 函数在堆中保留一块内存并返回一个通用的 void 指针。但是,代码将此指针分配...
    编程 发布于2024-11-08
  • 如何在 Zend Framework 中确定客户端的时区?
    如何在 Zend Framework 中确定客户端的时区?
    客户端时区确定确定客户端时区对于时间敏感的应用程序至关重要。这个问题探讨了如何在 Zend Framework 中获取此信息。以秒偏移量形式检索时区获取时区的首选方法是作为距 UTC 的秒数。例如,俄罗斯莫斯科将返回 36060,而英国伦敦将返回 0。建议的解决方案建议的解决方案涉及利用jQuery...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3