ES6 的迭代器 (Iterator) 和生成器 (Generator) 使用技巧

阅读时长 8 分钟读完

迭代器 (Iterator) 和生成器 (Generator) 是 ES6 中非常重要的两个新特性,它们的出现极大地简化了 JavaScript 编程中对于集合型数据的操作。本文将详细介绍迭代器和生成器的概念、语法以及使用技巧,旨在帮助前端开发者更好地掌握这些新特性的使用。

迭代器 (Iterator)

在 JavaScript 中,如果想要遍历一个集合,通常需要使用 for 循环或者 forEach 方法。但是在 ES6 中,我们可以通过迭代器的方式来遍历一个集合,迭代器是一种统一的遍历集合数据的方式。迭代器通过一个 next 方法来返回集合中的每一个元素,直到集合中的所有元素被遍历完为止。

迭代器的语法

ES6 中标准的迭代器语法如下:

在上面的代码中,我们通过数组的 [Symbol.iterator]() 方法来获取其迭代器对象,然后通过迭代器对象的 next() 方法,依次输出数组中的每个元素。当遍历完数组中的所有元素后,next() 方法会返回 {value: undefined, done: true},表示遍历结束。

自定义迭代器

除了使用数组的迭代器对象,我们也可以自定义一个迭代器对象,实现集合的遍历操作。若要实现一个迭代器对象,必须实现一个 next() 方法,并且该方法返回一个包含 valuedone 属性的对象。

-- -------------------- ---- -------
--- --- - -
  ----- --- -- ---
  ------------------- -
    --- ----- - --
    --- ---- - ----------
    --- ------ - ------------

    ------ -
      ------ -
        -- ------ - ------- -
          ------ -
            ------ --------------
            ----- ------
          --
        - ---- -
          ------ -
            ------ ----------
            ----- -----
          --
        -
      --
    --
  --
--

--- -------- - -----------------------

----------------------------- -- ------- -- ----- ------
----------------------------- -- ------- -- ----- ------
----------------------------- -- ------- -- ----- ------
----------------------------- -- ------- ---------- ----- -----

上面的代码中,我们自定义了一个对象 obj,并实现了其迭代器对象的 next() 方法,通过 obj 的 [Symbol.iterator]() 方法获取其迭代器对象,再通过迭代器对象的 next() 方法,依次输出 obj 中的每个值。

可迭代对象

除了使用自定义迭代器对象,我们也可以让对象变为可迭代对象,从而可以直接使用 for 循环或者 forEach 方法进行遍历。

-- -------------------- ---- -------
--- --- - -
  ----- --- -- ---
  ------------------- -
    --- ----- - --
    --- ---- - ----------
    --- ------ - ------------

    ------ -
      ------ -
        -- ------ - ------- -
          ------ -
            ------ --------------
            ----- ------
          --
        - ---- -
          ------ -
            ------ ----------
            ----- -----
          --
        -
      --
    --
  --
  ------------------ --------- -- -
    --- ----- - --
    --- ---- - ----------
    --- ------ - ------------

    ----- ------ - ------- -
      ----- --------------
    -
  --
--

--- ---- - -- ---- -
  ---------------
-

--------------------- -- -
  ---------------------
---

上面的代码中,我们通过 [Symbol.iterator]: function* () {...} 的语法将 obj 转化为可迭代对象,并支持使用 for 循环和 forEach 方法进行遍历。

生成器 (Generator)

生成器 (Generator) 是 ES6 中的另一个重要新特性,它可以通过 yield 语句实现暂停函数的执行,从而实现函数执行过程的控制。

生成器的语法

生成器的语法和普通函数基本一致,不同之处在于函数名前面要加上一个星号*,且函数体内可以包含 yield 语句。通过 yield 语句,函数可以在执行到该语句时暂停,并返回一个值,等待下一次调用时继续从该语句开始执行。

-- -------------------- ---- -------
--------- ------------- -
  ----- --
  ----- --
  ----- --
-

--- -------- - --------------

----------------------------- -- ------- -- ----- ------
----------------------------- -- ------- -- ----- ------
----------------------------- -- ------- -- ----- ------
----------------------------- -- ------- ---------- ----- -----

上面的代码中,我们定义了一个生成器函数 myGenerator(),函数体内含有三个 yield 语句,通过调用 iterator.next() 方法,依次输出每个 yield 语句的返回值。当生成器函数执行完所有的 yield 语句后,再次调用 next() 方法时便会返回 {value: undefined, done: true}

生成器实现异步编程

生成器可以通过 yield 语句暂停函数执行,然后由 next() 方法再次继续函数执行过程。我们可以基于这个特性,实现异步编程的效果。

-- -------------------- ---- -------
-------- --------- -
  ------ --- ----------------- ------- -- -
    --- --- - --- -----------------
    --------------- -----
    ---------------------- - -------- -- -
      -- --------------- --- -- -
        -- ----------- --- ---- -
          --------------------------
        - ---- -
          -------------------
        -
      -
    --
    -----------
  ---
-

--------- --------------- -
  --- -
    --- ------- - ----- -------------
    ---------------------
    --- ------- - ----- -------------
    ---------------------
    --- ------- - ----- -------------
    ---------------------
  - ----- ------- -
    -------------------
  -
-

--- -------- - ----------------
--- ------- - ----------------------

-------
  -------------- -- -
    ----------------------------------------- -- -
      ----------------------
    ---
  --
  -------------- -- -
    -------------------
  ---

上面的代码中,我们定义了一个生成器函数 ajaxGenerator(),通过三个 yield ajax(url) 语句实现了三次异步请求,当所有异步请求完成后,在控制台输出每个请求的结果。我们通过调用 iterator.next().value 获取第一个异步任务的 Promise 对象,然后通过 promise.then() 语句的链式调用实现异步任务的串行执行。

总结

以上就是迭代器 (Iterator) 和生成器 (Generator) 的详细介绍和使用技巧,通过学习这些新特性可以更加轻松地操作集合型数据,同时也能够更好地理解 JavaScript 异步编程的实现原理。在实际的开发过程中,我们可以根据具体的业务场景灵活地运用这些技巧,提高代码的效率和可读性。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6461ac7b968c7c53b0306560

纠错
反馈