深入解析ES6+新語法:復雜的迭代器與生成器

?一、迭代器(Iterator):數據遍歷的統一協議 ?

1. 迭代器協議的本質

**迭代器協議(Iterator Protocol)** 是一種標準化的數據訪問接口,它要求對象實現一個 `next()` 方法,每次調用返回包含 `{ value, done }` 的對象。 ?
- **`value`**: 當前遍歷的值 ?
- **`done`**: 布爾值,表示遍歷是否結束 ?

const arrayIterator = {data: [1, 2, 3],index: 0,next() {return this.index < this.data.length?? { value: this.data[this.index++], done: false }: { value: undefined, done: true };}
};console.log(arrayIterator.next()); // { value: 1, done: false }

此迭代器通過內部維護的 `index` 狀態,逐步遍歷數組元素。

?2. 可迭代對象(Iterable) ?

若對象實現了[Symbol.iterator]()?方法,則稱為 可迭代對象。該方法返回一個迭代器,使得對象可被 `for...of` 等語法消費。

自定義可迭代鏈表:??

class LinkedList {constructor() {this.nodes = [];}add(node) {this.nodes.push(node);}[Symbol.iterator]() {let index = 0;return {next: () => ({value: this.nodes[index++],done: index > this.nodes.length})};}
}const list = new LinkedList();
list.add('a'); list.add('b');
for (const node of list) {console.log(node); // 'a', 'b'
}

?二、生成器(Generator):迭代器的超級語法糖 ?

1. 生成器的核心機制

生成器函數(function*)返回一個 生成器對象,該對象既是迭代器,也是可迭代對象。其核心能力在于: ?
- 暫停與恢復執行:通過 `yield` 關鍵字中斷函數,保留上下文狀態 ?
- 雙向通信:`yield` 可向外傳遞值,外部可通過 `next(arg)` 向內注入值 ?生成器執行流程 ?

function* gen() {const a = yield 1;const b = yield a + 2;yield b * 3;
}const g = gen();
console.log(g.next()); ? ? ?// { value: 1, done: false }
console.log(g.next(10)); ? ?// { value: 12, done: false } (a = 10)
console.log(g.next(5)); ? ? // { value: 15, done: false } (b = 5)
console.log(g.next()); ? ? ?// { value: undefined, done: true }

**關鍵點**:每次 `next(arg)` 的 `arg` 會賦值給左側 `yield` 表達式的返回值。

2. 生成器的底層模型 ?

生成器本質是 **協程(Coroutine)** 的輕量級實現。與線程不同,協程的切換由開發者顯式控制,且不涉及系統內核,因此極其高效。 ?

- 執行上下文棧:生成器暫停時,其執行上下文(變量、作用域鏈)被保存,恢復時重新壓入棧頂 ?
- 狀態機轉換:Babel 等工具將生成器轉換為帶有 `switch-case` 的狀態機代碼 ?

?三、高級應用場景 ?

1. 異步流程控制:生成器的革命性貢獻 ?

在 `async/await` 普及前,生成器 + Promise 是處理異步代碼的終極方案,其核心模式如下: ?

實現自動執行器 ?

function run(generator) {const g = generator();function handle(result) {if (result.done) return result.value;return result.value.then(data => handle(g.next(data)),err => handle(g.throw(err)));}return handle(g.next());
}run(function* fetchUser() {const user = yield fetch('/api/user');const posts = yield fetch(`/api/posts?userId=${user.id}`);return { user, posts };
}).then(data => console.log(data));

此模式直接催生了 `async/await` 的誕生,兩者在 Babel 中被編譯為類似的生成器代碼。

?2. 無限數據流與惰性計算 ?

生成器天然適合處理大規模或無限序列,僅在需要時計算值,避免內存爆炸。

斐波那契數列 ?

function* fibonacci() {let [prev, curr] = [0, 1];while (true) {yield curr;[prev, curr] = [curr, prev + curr];}
}const seq = fibonacci();
console.log(seq.next().value); // 1
console.log(seq.next().value); // 1
console.log(seq.next().value); // 2
// 可無限調用,但每次只計算一個值

3. 復雜狀態機 ?

生成器通過 `yield` 管理狀態轉移,代碼比傳統狀態機更簡潔。

?交通燈狀態機 ?

function* trafficLight() {while (true) {yield 'Red';          // 返回 'Red'yield delay(3000);   // 返回 Promise,暫停 3 秒yield 'Green';        // 返回 'Green'yield delay(2000);   // 返回 Promise,暫停 2 秒yield 'Yellow';       // 返回 'Yellow'yield delay(1000);   // 返回 Promise,暫停 1 秒}
}function delay(ms) {return new Promise(resolve => setTimeout(resolve, ms));
}// 使用
const light = trafficLight();function runTrafficLight() {const { value, done } = light.next();if (done) return; // 如果生成器結束,退出if (typeof value === 'string') {console.log(value); // 更新 UI 為當前顏色runTrafficLight();  // 繼續下一步} else if (value instanceof Promise) {value.then(() => runTrafficLight()); // 等待 Promise 完成后再繼續}
}runTrafficLight(); // 啟動交通燈

四、生成器與迭代器的未來 ?

1. 異步迭代器(Async Iterator) ?

ES2018 引入的異步迭代器,允許迭代異步數據源(如數據庫流、WebSocket): ?
async function* asyncCounter() {let i = 0;while (i < 3) {await sleep(1000);yield i++;}
}
(async () => {for await (const num of asyncCounter()) {console.log(num); // 0, 1, 2(每秒輸出一個)}
})();

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898248.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898248.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898248.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LangChain介紹(開源大語言模型LLM應用構建框架,提供完整工具和組件,使開發者能夠創建復雜、交互式且上下文感知的LLM應用)LangServe

文章目錄 LangChain&#xff1a;構建LLM應用的強大框架引言LangChain核心理念- 超越模型訓練數據的局限性- 訪問最新信息- 與外部系統交互- 執行復雜推理鏈 核心組件體系1. 模型&#xff08;Models&#xff09;- **LLMs**&#xff1a;如OpenAI、Anthropic、Cohere等提供的完成型…

微軟 System Center Configuration Manager(SCCM)的組件文件

微軟 System Center Configuration Manager(SCCM) 或 Microsoft Endpoint Configuration Manager(MECM) 的組件文件,屬于企業級設備管理工具的一部分。以下是具體說明: C:\Windows\CCM\smsswd.exe C:\Windows\CCM\tsmanager.exe smsswd.exe 和 tsmanager.exe 是 Micros…

Java設計模式建模語言面向對象設計原則

設計模式 設計模式的概念 設計模式最初用于建筑領域的設計中。 軟件的設計模式&#xff0c;又稱設計模式&#xff0c;是一套被反復使用&#xff0c;多數人知道的&#xff0c;經過分類編目的&#xff0c;代碼設計經驗的總結。 它描述了在軟件設計過程中的一些不斷重復發生的…

uniapp 實現微信小程序電影選座功能

拖動代碼 /*** 獲取點擊或觸摸事件對應的座位位置* 通過事件對象獲取座位的行列信息* param {Event|TouchEvent} event - 點擊或觸摸事件對象* returns {Object} 返回座位位置對象&#xff0c;包含行(row)和列(col)信息&#xff0c;若未找到有效位置則返回 {row: -1, col: -1}*…

Docker - 切換源 (Linux / macOS)

文章目錄 Linux 系統macOS 系統 Linux 系統 修改配置文件&#xff1a;/etc/docker/daemon.json "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","https://hub-mirror.c.163.com"]驗證是否修改成功&#xff1a; docker info重啟 …

RocketMQ的安裝及配置(windows)

1. 環境準備 JDK需要先安裝好。 1. RocketMQ是用Java語言寫的&#xff0c;所以需要JDK的支持。2. 下載RocketMQ 建議下載這個低版本的 https://rocketmq.apache.org/release-notes/2020/12/21/4.8.0/ 下載之后解壓即可&#xff0c;目錄結構如下&#xff1a; 3. 配置RocketM…

【運維自動化-標準運維】如何實現一個最簡單的流程編排

流程編排是標準運維最核心的功能&#xff0c;通過將不同功能的原子插件在畫布上可視化的拖拽編排&#xff0c;可以實現各種不同場景的跨系統工作流。標準運維流程 根據實際運維操作場景梳理出來的操作步驟&#xff0c;通過不同的流轉邏輯&#xff08;并行、分支、條件并行&…

性能測試之grafana展示jmeter測試指標與主機監控

性能測試之grafana展示jmeter測試指標與主機監控 背景 ? 公司新的項目準備開展性能測試,之前性能監控主要使用的jmeter的插件jpgc-Transactions per Second 與 jpgc- Response Times Over Time 與 jpgc - Active Threads Over Time等等插件監控性能指標結果,PerfMon Metrics…

1~2 課程簡介+ESP32-IDF環境搭建(虛擬機Linux環境下)

嗶站“宸芯IOT”視頻鏈接 一、課程內容介紹 1.什么是ESP32 ESP32是集成2.4GHz Wi-Fi和藍牙雙模的單芯片方案&#xff0c;具有超高的射頻性能、穩定性、通用性和可靠性&#xff0c;以及超低的功耗&#xff0c;滿足不同的功耗需求&#xff0c;適用于各種應用場景。ESP32是ESP8…

Vue3一個組件綁定多個 v-model,自定義 prop 和 event 名稱

Vue3一個組件綁定多個 v-model&#xff0c;自定義 prop 和 event 名稱 Vue3中v-model默認使用modelValue作為prop&#xff0c;update:modelValue作為事件&#xff0c;而Vue2使用的是value和input。此外&#xff0c;Vue3允許通過參數的方式為組件添加多個v-model綁定&#xff0…

YOLOv11小白的進擊之路(九)創新YOLO11損失函數之NWD損失函數源碼解讀

之前的博客也有對YOLO11的損失函數進行過源碼分析&#xff0c;可以參考&#xff1a;YOLOv11小白的進擊之路&#xff08;六&#xff09;創新YOLO的iou及損失函數時的源碼分析_yolov11的損失函數是什么-CSDN博客最近在做小目標檢測的時候注意到了NWD損失函數&#xff0c;這里對其…

VLN 論文精讀(四)Dynamic Path Navigation for Motion Agents with LLM Reasoning

這篇筆記用來描述2025年發表在arxiv上的一篇有關VLN領域的論文&#xff0c;由港科大和達特茅斯大學聯合發布&#xff0c;其核心思想有以下幾點&#xff1a; 將3D環境轉化為2D平面&#xff1b;2D平面中障礙物分布、機器人起點與終點信息用稀疏矩陣形式進行描述&#xff1b;與LL…

vue3之寫一個aichat ----vite.config.js

vite.config.js的CSS配置 postcss-pxtorem 開發響應式網頁的時候需要用到postcss-pxtorem amfe-flexible amfe-flexible是由阿里團隊開發的一個庫&#xff0c;它可以根據設備的屏幕寬度去動態調整HTML根元素()的字體大小&#xff0c;這意味著無論用戶使用什么尺寸的設備訪問你…

寶石PDF,全新 PC 版本,全部免費

寶石PDF已經運行 3 年時間&#xff0c;有客戶端&#xff0c;小程序&#xff0c;一直未上 PC 版本&#xff0c;隨著客戶端功能升級的不及時&#xff0c;很多用戶建議上 PC 版本。但是飛哥一直忙&#xff0c;這不終于給上了。 同時系統的名稱也從 “PDF云轉換”改為“寶石PDF”&…

.NET8使用EF Core連接SQLite

使用框架 .NET8 在nuget中&#xff0c;需要安裝包&#xff1a; SQLitePCLRaw.bundle_e_sqlite3&#xff0c;版本 2.1.10 Microsoft.EntityFrameworkCore.Sqlite.Core&#xff0c;版本 9.0.0 using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microso…

HTML課后實踐

實驗一 【實驗原理】 在搜索引擎的文本分析中&#xff0c;標題的信息權重要比正文的大&#xff0c;所以標題的樣式非常重要。本實驗通過把標題標記和常規文本進行對比輸出&#xff0c;掌握標題標簽的用法。在網頁中&#xff0c;有時需要為文字設置粗體、斜體或下劃線效果&#…

【紫光同創FPGA開發常用工具】FPGACPLD的下載與固化

文檔內容適配技術問題說明&#xff08;非正文&#xff09;&#xff1a; 1、FPGA&CPLD如何下載位流文件&#xff1b; 2、FPGA外部flash如何固化位流文件&#xff1b; 3、PDS軟件燒錄界面如何新增用戶flash&#xff1b; 4、CPLD內部flash如何固化位流文件&#xff1b; F…

前端傳參+后端接參對照

? Java 后端參數接收注解 & 前端傳參格式對照 后端注解前端 Content-Type前端傳參方式說明RequestParamapplication/x-www-form-urlencodedURL參數 / form表單提交 / Postman form-data常用于 keyvalue 形式的參數&#xff1b;適合少量簡單參數RequestParamURL拼接/api/t…

計算機網絡的框架結構

計算機網絡課程知識體系框架 一、計算機網絡基礎概念 1.1 網絡組成要素 端系統&#xff08;主機、服務器&#xff09;通信鏈路&#xff08;有線/無線介質&#xff09;交換設備&#xff08;路由器、交換機&#xff09;協議體系&#xff08;TCP/IP協議簇&#xff09; 1.2 網絡…

塔能智慧物聯節能方案:點亮城市,賦能工廠

在全球積極倡導節能減排、綠色發展的時代背景下&#xff0c;塔能&#xff08;江蘇&#xff09;科技有限公司憑借其創新的智慧物聯節能一體化解決方案&#xff0c;在城市照明和工廠節能領域取得了顯著成果。該方案不僅為城市的夜晚帶來了明亮且節能的照明&#xff0c;還為工廠的…