随着前端应用变得越来越复杂,异步编程(asynchronous programming)已成为非常重要的一部分,但在使用 Promise、async/await 等异步编程技术时也会遇到一些问题,例如 Promise.all() 和 Promise.race() 方法只处理 Promise 实例,而很难处理多个异步迭代器,此时 for-await-of 很好地解决了这个问题。
ES2018 推出的 for-await-of 允许我们处理异步可迭代对象(async iterable),它是在 for-of 循环基础上升级而来,可以在循环中使用 await 关键字来处理异步迭代器中的返回值,这极大地简化了代码语法,提高了可读性和可维护性。
什么是异步 Iterable?
在学习 for-await-of 之前,我们需要了解异步迭代器(async iterator),它是同时满足以下两个条件的迭代器:
- 它是一个迭代器,实现了 next() 方法,返回包含 value 和 done 属性的对象。
- 它指示下一个元素何时可用,即 next() 方法返回一个 Promise,而不是立即返回。
异步迭代器可以使用 Symbol.asyncIterator 方法来定义。以下是示例代码:
-- -------------------- ---- ------- ----- ------------- - - ------------------------ - --- - - -- ------ - ----- ------ - -- -- - -- - ----- --- --------------- -- ------------------- ------- ------ - ------ ---- ----- ----- -- - ------ - ----- ---- -- - -- - --
在上面的代码中,我们用 Symbol.asyncIterator 方法返回了一个迭代器对象,实现 next() 方法,并在每个执行周期之间等待 1 秒钟。
for-await-of 使用方法
与传统的 for-of 循环语法类似,for-await-of 提供了一种遍历异步迭代器的语法。以下是示例代码:
async function foo() { for await (let value of asyncIterable) { console.log(value); } } foo();
在上面的代码中,使用 for-await-of 语句来遍历 asyncIterable。因为 asyncIterable 迭代器是异步的,所以我们使用了 async function 来包装整个 for-await-of 循环。使用 await 关键字使我们可以在每个完成的循环周期中访问 value 变量。
示例
让我们使用 for-await-of 迭代器来处理异步可迭代对象(异步 Generator)的实际案例。
假设我们有一个数组,其中每个元素都是一个 Promise 对象,而实际的值只能通过异步获取。如果我们要访问数组中的所有值,就需要等到所有 Promise 都完成,而且顺序不能错。
以下是示例代码:
-- -------------------- ---- ------- ----- -------- - - --- --------------- -- ------------- -- --------------- ------- --- --------------- -- ------------- -- --------------- ------- --- --------------- -- ------------- -- ----------------- ------ -- ----- -------- ----- - --- ----- ---- ----- -- --------- - ------------------- - - ------
在上面的代码中,我们创建了一个仅包含 Promise 对象的数组,并使用 for-await-of 语句来访问它们。每个 Promise 对象使用 setTimeout 模拟异步获取。使用 for-await-of 可以确保在所有 Promise 对象都被解决之前,不会访问打印值。
结论
使用 for-await-of 可以简化处理异步迭代器的代码语法,并使代码更具可读性和可维护性。在处理 Promise、异步 Generator 等异步可迭代对象时,for-await-of 可以轻松地帮助我们处理异步返回值,让代码更加清晰明了。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66fd9c0344713626017fbbc3