在 JavaScript 中,迭代器(Iterator)是一个非常常用的概念。ES6 引入了迭代器的概念,并且在之后的 ES8 中又引入了一种叫做异步迭代器(AsyncIterator)的新概念。而在 ES10 中,我们又可以看到同步异步迭代器的新特性。
迭代器
在 JavaScript 中,迭代器的作用是让我们能够依次访问某个集合中的元素,而不需要暴露这个集合的内部细节。比如在 ES6 的 for...of
循环中,就使用了迭代器的概念,它能够遍历一个可迭代对象(Iterable)中的每一个元素。
可以通过一个例子来更好地理解迭代器的概念。假设我们有一个数组 arr
,现在我们要依次访问数组中的元素:
const arr = [1, 2, 3]; for (const el of arr) { console.log(el); }
上面的代码中,arr
是一个可迭代对象,我们可以通过 for...of
循环遍历这个数组中的每一个元素。在 for...of
循环的过程中,实际上是通过数组的迭代器来取出每一个元素的。
异步迭代器
在某些情况下,我们需要对一个集合中的元素进行异步操作。这时候,ES8 中引入的异步迭代器就非常有用了。异步迭代器的概念和同步迭代器类似,不过它的 next
方法返回的是一个 Promise 对象,并且支持使用 await
关键字来异步访问集合中的元素。
实际上,异步迭代器的实现原理也很简单。我们只需要在原来的同步迭代器的基础上,将取出元素的过程改成异步的,就可以实现异步迭代器了。
下面是一个使用异步迭代器的例子。假设我们有一个异步的生成器函数 getAsyncData
,它每次返回一个随机的数字,我们要通过异步迭代器遍历这个函数生成的数字序列:
-- -------------------- ---- ------- ----- --------- -------------- - ----- ------ - ----- --- --------- -- ------------- ------- ----- -------------- - - ----- -------- ------ - --- ----- ------ -- -- --------------- - ---------------- - - -------展开代码
如上所示,我们可以使用 for...await...of
循环来遍历异步生成器函数返回的每一个元素,await
关键字可以等待异步过程完成后再进行下一步操作。
同步异步迭代器
在 ES10 中加入的新特性就是同步异步迭代器。同步异步迭代器的作用相当于将同步迭代器和异步迭代器结合在一起,使得我们可以在同一个迭代器中既可以支持同步操作,也可以支持异步操作。
同步异步迭代器的实现原理也很简单,我们只需要在迭代器的内部去判断一个元素是否为 Promise 对象,如果是 Promise 对象,我们就可以将这个迭代器标记为异步迭代器,否则就是同步迭代器。
下面是一个使用同步异步迭代器的例子。我们有一个异步生成器函数 getAsyncData
,在每个元素之间等待 1 秒钟,而且这个元素可能是一个同步的值,也可能是一个异步的 Promise 对象。我们要通过同步异步迭代器来遍历这个生成器函数返回的结果:
-- -------------------- ---- ------- ----- --------- -------------- - ----- -- ----- --- --------- -- ------------- ------- ----- ------------------- - ----- -------- ------ - ----- ------ - --- --- ----- ------ -- -- --------------- - ---------------- - -------------------- - -------展开代码
如上所示,我们可以使用 for await...of
循环来遍历这个异步生成器函数返回的结果,即使这个结果既包含同步的值,也包含异步的 Promise 对象。在遍历的过程中,我们可以使用 await
关键字来等待异步操作完成后,继续执行下一步操作。
学习和指导意义
同步异步迭代器是 ES10 中新增的一个特性,它的出现让我们在使用迭代器的时候更加灵活。特别是在对异步数据进行处理的时候,同步异步迭代器非常实用。通过学习同步异步迭代器的原理和使用方法,我们可以更好地理解 JavaScript 中迭代器和异步操作的本质和挑战。在实际的项目中,我们也可以使用同步异步迭代器来更加高效地处理异步数据。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67c14b96314edc268492607b