」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 了解 JavaScript 產生器:強大的程式碼流控制工具

了解 JavaScript 產生器:強大的程式碼流控制工具

發佈於2024-11-08
瀏覽:612

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]刪除
最新教學 更多>
  • 大泥球:理解反模式以及如何避免它
    大泥球:理解反模式以及如何避免它
    前端开发中最臭名昭著的架构反模式可能是大泥球。术语“大泥球”适用于没有明显结构或模块化组织的系统。代码库有机且混乱地增长,成为维护的噩梦。这是许多开发人员发现自己所处的情况,特别是当他们面临着按时完成任务并开发大量功能的压力时。 这就是当前文章的内容:大泥球反模式以及前端开发中的示例,为什么它如此常...
    程式設計 發佈於2024-11-08
  • 如何正確使用帶有 Map 參數的“reflect.Call”函數?
    如何正確使用帶有 Map 參數的“reflect.Call”函數?
    解決reflect套件中的.Call使用問題在reflect套件中使用.Call函數時,遵守所需的參數格式至關重要。本文將引導您完成正確使用 .Call 函數並操作 in 變數以滿足目標方法的過程。 提供的範例程式碼中:params := "some map[string][]string...
    程式設計 發佈於2024-11-08
  • 如何使用 HTML 和 CSS 建立翻頁卡動畫
    如何使用 HTML 和 CSS 建立翻頁卡動畫
    在這篇文章中,我們將了解如何使用 HTML 和 CSS 以及漸變背景創建時尚的 3D 翻轉卡片動畫。 造訪我的網站 了解結構 我們將使用卡片的兩側(正面和背面)來創造翻轉效果。此效果將在懸停時使用 CSS 過渡啟動。 <div class="card"> &l...
    程式設計 發佈於2024-11-08
  • Python 中的 len() 函數有多有效率?
    Python 中的 len() 函數有多有效率?
    Python 中len() 函數的成本影響len() 函數是Python 內建功能的組成部分,提供各種資料結構的長度的資訊。具體來說,它通常與列表、元組、字串和字典一起使用,以確定它們所包含的元素或字元的數量。 與直覺的感知相反,len() 函數的計算成本保持不變跨越所有上述資料型態。這意味著無論列...
    程式設計 發佈於2024-11-08
  • 如何在 Java 中將 Long 值轉換為位元組數組並返回?
    如何在 Java 中將 Long 值轉換為位元組數組並返回?
    在Java 中將Long 轉換為位元組數組並傳回在Java 中,將long 基本資料型別轉換為位元組數組(byte[] ),反之亦然是各種操作的常見任務,例如透過TCP 連線發送資料。以下是實現此轉換的全面解決方案:Long 到 Byte Arraypublic byte[] longToBytes...
    程式設計 發佈於2024-11-08
  • 如何使用 JavaScript 從 iFrame 重新導向父視窗?
    如何使用 JavaScript 從 iFrame 重新導向父視窗?
    從iFrame 重定向父視窗如果父視窗中嵌入了iFrame,則可能需要重定向父視窗視窗的位置更改為新的URL。為了實現這一點,JavaScript 提供了一個簡單的解決方案。 使用JavaScript 重新導向父視窗在iFrame 的JavaScript 程式碼中,您可以使用以下方法: 重定向最頂層...
    程式設計 發佈於2024-11-08
  • 如何在 Python 中以空格分割字串,同時保留引用的子字串?
    如何在 Python 中以空格分割字串,同時保留引用的子字串?
    在Python 中按空格分割字串同時保留帶引號的子字串處理同時包含空格和帶引號的子字符當字串的字串時,可能會遇到困難準確地分割字串,同時保持引用部分的完整性。在 Python 中,shlex 模組為此特定場景提供了解決方案。 使用shlex.split() 保留引號shlex.split() 函數可...
    程式設計 發佈於2024-11-08
  • 如何使用 Selenium 在 Google Chrome 模擬 Microsoft Edge Mobile?
    如何使用 Selenium 在 Google Chrome 模擬 Microsoft Edge Mobile?
    使用Selenium 更改Google Chrome 中的用戶代理在Selenium 自動化腳本中,為瀏覽器視窗設定特定的用戶代理對於模擬設備行為和確保網站渲染至關重要正如預期的那樣。在這種情況下,我們的目標是將 Google Chrome 中的使用者代理程式修改為 Microsoft Edge M...
    程式設計 發佈於2024-11-08
  • NPM 對等依賴關係深入:全面介紹
    NPM 對等依賴關係深入:全面介紹
    作為 Javascript 開發者,我們都知道專案中存在兩種不同的依賴關係,dependency 和 devDependency,但是peerDependency 又如何呢? 在本系列中,我們將研究 Javascript 中這種較不常見的依賴關係。我們將研究它們是什麼,作為圖書館使用者我需要了解什...
    程式設計 發佈於2024-11-08
  • 哪種 MySQL 取得函數適合您的 PHP 應用程式:`mysql_fetch_array`、`mysql_fetch_assoc` 和 `mysql_fetch_object` 的比較
    哪種 MySQL 取得函數適合您的 PHP 應用程式:`mysql_fetch_array`、`mysql_fetch_assoc` 和 `mysql_fetch_object` 的比較
    比較mysql_fetch_array、mysql_fetch_assoc 和mysql_fetch_object:綜合分析mysql 函數系列在從MySQL 函式中擷取結果起至關重要的查詢作用在PHP 中。在這些函數中,mysql_fetch_array、mysql_fetch_assoc 和 m...
    程式設計 發佈於2024-11-08
  • Lerna – Monorepo 管理的關鍵
    Lerna – Monorepo 管理的關鍵
    歡迎回到莫諾雷波城堡! 現在城堡已經建成,每個房間(項目)都已就位。但如果沒有正確的管理,事情可能會變得混亂。誰來幫助城堡順利運作?這時勒納登場了──一位強大的巫師,擁有神奇的命令,可以讓一切保持秩序。 Lerna 是您在 monorepo 土地上的嚮導,確保所有房間(項目)同步,所有包都鏈接,...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中循環嵌套數組並顯示特定值?
    如何在 PHP 中循環嵌套數組並顯示特定值?
    PHP foreach 與嵌套數組:綜合指南在 PHP 中,瀏覽嵌套數組可能是常見的挑戰。本討論重點討論特定場景,您的目標是顯示嵌套數組的子集,特別是第二個嵌套數組中的值。 將foreach 與嵌套數組結合使用要使用foreach 處理嵌套數組,您可以使用以下命令方法:]範例:$tmpArray =...
    程式設計 發佈於2024-11-08
  • 提升 Web 效能:前端開發人員指南
    提升 Web 效能:前端開發人員指南
    大家好!自从我上次写博客以来已经有一段时间了,我承认,这让我有点难过。现实是,有太多东西需要学习,有时感觉永远没有足够的时间来深入了解所有内容。我在跟谁开玩笑呢?事实是,我最近拖延得很厉害。 但最近,我一直在探索网络性能——这对于任何前端开发人员来说都是一个至关重要的话题——我很高兴分享我所学到的东...
    程式設計 發佈於2024-11-08
  • 如何利用先進的加密技術增強資料保護?
    如何利用先進的加密技術增強資料保護?
    對稱金鑰加密:FernetPython 擁有強大的加密庫,提供Fernet,這是一種安全、最佳實踐的加密方案。 Fernet 採用 AES CBC 加密、HMAC 簽章以及版本和時間戳記資訊來保護資料。建議使用 Fernet.generate_key() 產生金鑰。 from cryptograph...
    程式設計 發佈於2024-11-08
  • 什麼是本地主機?本地主機作為開發人員的用途
    什麼是本地主機?本地主機作為開發人員的用途
    您有沒有想過當開發人員在將網站上線之前測試網站時會發生什麼?或者網路管理員如何檢查他們的系統是否正常運作?答案在於一個強大但經常被誤解的概念,稱為 localhost。讓我們深入了解 localhost 是什麼、為何它很重要以及它如何變得非常有用。 什麼是本地主機? 用最簡單的術語...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3