首页/文章/javascript

你知道生成器和迭代器是啥玩意吗

2024-09-02
8393 分钟
...

迭代器和生成器

迭代器和生成器是为了完成函数的中断效果而出现的。让原本只能一次性执行完的函数具备分段处理的功能。在本质上,这两者都属于函数的一种。

迭代器

官方介绍:在 JavaScript 中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个返回值。更具体地说,迭代器是通过使用 next() 方法实现 Iterator protocol 的任何一个对象,该方法返回具有两个属性的对象: value,这是序列中的 next 值;和 done ,如果已经迭代到序列中的最后一个值,则它为 true 。如果 value 和 done 一起存在,则它是迭代器的返回值。

简单的来说就是:迭代器本身就只是_具备闭包_和_对返回值有格式要求_的并且使用next()方法进行调用的一个函数而已。

让我们手撸一个了解一下。

//自定义迭代器
function makeRangeIterator(start = 0, end = Infinity, step = 1) {
    let nextIndex = start
    let iterationCount = 0

    const rangeIterator = {
       next: function() {
           let result
           //判断是否具备继续执行的条件
           if (nextIndex < end) {
               result = { value: nextIndex, done: false }
               nextIndex += step
               iterationCount++
               return result
           }
           return { value: iterationCount, done: true }
       }
    }
    //不同于寻常了解的闭包,这里返回的是一个对象而非函数
    return rangeIterator
}

//初始化按迭代器功能。
let it = makeRangeIterator(1, 10, 2)

//进行next的调用
let result = it.next()
//判断是否需要继续执行
while (!result.done) {
 console.log(result.value)
 result = it.next()
}

console.log("Iterated over sequence of size: ", result.value)

以上方形式出现的函数,就是被我称为迭代器的东西。

生成器

但这种自定义的迭代器有一个比较麻烦的地方是:需要我们自己去维护内部的状态,去编写内部的逻辑。

所以,_生成器_出现了。

生成器的官方介绍:生成器函数提供了一个强大的选择:它允许你定义一个包含自有迭代算法的函数,同时它可以自动维护自己的状态。生成器函数使用 function*语法编写。最初调用时,生成器函数不执行任何代码,而是返回一种称为 Generator 的迭代器。通过调用生成器的下一个方法消耗值时,Generator 函数将执行,直到遇到 yield 关键字。

生成器对迭代器进行了下一层的封装。生成器内置了迭代器的业务逻辑。并为我们提供了语法糖。

上方迭代器的案例以生成器的形式再完成一遍如下👇

function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
    console.log(1);
      console.log(2);
    yield "第一次停顿,执行打印1,2";
      console.log(3);
      console.log(4);
     yield"第二次停顿,执行打印3,4";
      console.log(5);
      console.log(6);
     yield "第三次停顿,执行打印5,6";
      console.log(7);
}
var a = makeRangeIterator(1,10,2)

a.next() //打印1,2和{value: '第一次停顿,执行打印1,2', done: false}
a.next() //打印3,4和{value: '第二次停顿,执行打印3,4', done: false}
a.next() //打印5,6和{value: '第三次停顿,执行打印5,6', done: false}
a.next() //{value: undefined, done: true}

我想这个例子很直观。每调用过一次 .next() 函数,就会在同一个上下文被标记为_yield_的地方停顿等待。

yield_是生成器函数的中断标记,当生成器函数运行到yield标记的地方时。必须使用_next();才可以继续执行,直到遇见到下一个_yield_或_函数结束_为止。

最后

这玩意在工作中有什么用?对于95%的开发来说,这玩意都没什么用。知道知道面试答的上来就好了。想碰到用它的场景都很难。

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
javascript2025-09-18
JavaScript 的多线程能力:Worker
如果你写过一些计算量稍大的 JavaScript 代码,比如图像处理、大量数据排序或者复杂的算法,你几乎肯定遇到过浏览器“卡死”的现象。点击页面没反应,动画也停了,就像整个世界都静止了。 这就是主线程被阻塞的典型后果。因为主线程既要负责执行 JavaScript,又要负责渲染页面、响应用户操作,一旦它被繁重的计算任务占满,就无暇顾及其他,用户体验便直线下降。 这个问题的根源,正是“主线程是单线程的”。那么,如何解决呢? 答案很简单:把这...
学习面试
javascript2025-09-10
手把手教你实现一个EventEmitter
你是不是也遇到过这种情况:代码里各种事件监听和触发,回调函数套了一层又一层,最后自己都理不清哪个事件先触发、哪个后触发了? 别担心,今天我就带你从零开始实现一个自己的事件触发器(EventEmitter),让你彻底掌握事件驱动的精髓,代码清晰度直接提升200%! 为什么要懂EventEmitter? 先说说为什么我们要关心这个。Node.js的核心就是事件驱动,比如文件读写、网络请求,都是通过事件来处理的。不会EventEmitter,...
学习面试
javascript2025-08-09
Web Worker 多线程魔法
你是否曾遇到过网页因为复杂计算而卡顿的情况?今天,让我们一起探索Web Worker的神奇世界,看看如何用多线程技术解决性能瓶颈,并实现流畅的图片压缩功能! 为什么需要Web Worker? 想象一下,你在一个繁忙的餐厅里,只有一位服务员(主线程)负责点餐、上菜、结账所有工作。当客人突然暴增时,这位服务员就会手忙脚乱,其他客人只能干等着… 这就是JavaScript的现状—— 单线程 !所有任务都在一个线程中排队执行,一旦遇到复杂计算(...
学习面试
javascript2025-08-07
🌐AST抽象语法树
AST 是前端开发中一个非常重要的概念,它就像是代码的“编译器”,能够帮助我们理解和操作代码。本文将深入探讨 AST 的原理和应用,带你从零开始了解 AST。 一、什么是 AST? AST(抽象语法树)是一种树形结构,用于表示程序代码的语法结构。它将代码分解为一系列的节点,每个节点代表代码中的一个元素,如变量、函数、表达式等。AST 是编译器和解释器的基础,也是代码分析和转换的关键工具。 1\. AST 的结构 AST 的结构通常包括以...
学习面试
javascript2025-08-05
打字机效果是如何实现的
分析效果 使用 AI 对话的时候,文字是一个字一个字蹦出来的?它不是等所有内容生成完毕后一次性展示,而是以一种流畅、实时的“打字机”效果呈现,这种体验的背后,隐藏着一种高效的Web技术。它就是 服务器推送事件(Server Sent Events,简称 SSE) 什么是 SSE 从根本上说,SSE 是一种允许服务器 单向 、 持续 地向客户端(浏览器)推送数据的Web技术。 可以把它想象成一个 电台广播 : 服务器 是广播电台,持续不断...
学习面试
javascript2025-08-04
Promise 从原理到实现
前言 是 异步编程的核心概念之一,它为我们提供了一种更优雅的方式来处理异步操作。 本文将全面剖析 的工作原理,并逐步实现一个符合 规范的 。 正文 一、Promise 基础概念 代表一个异步操作的最终完成(或失败)及其结果值。它有 种状态: 1. pending : ,既不是成功,也不是失败状态 2. fulfilled :意味着操作 完成 3. rejected :意味着操作 状态一旦改变就不能再变,只能从 变为 ,或从 变为 。 二...
学习面试

评论

请登录后发表评论

去登录
加载评论中...

目录