前端开发中,异步编程是非常常见的问题,而 ES2018 引入的 for async/of
以及 AsyncIterator
则为我们提供了一些更好的异步编程解决方案。
本文将详细介绍 for async/of
和 AsyncIterator
,并通过示例代码演示如何使用它们来提高我们异步编程的效率和可读性。
异步迭代器
在介绍 for async/of
之前,我们先来了解一下异步迭代器(AsyncIterator
)。异步迭代器是一种特殊类型的迭代器,它的 next
方法返回的是一个 Promise。这种迭代器通常被用在异步编程中,例如遍历一个异步生成器的结果。
一个异步迭代器的基本示例如下:
// javascriptcn.com 代码示例 async function* asyncGenerator() { yield 1; // yield 1 等待 100 毫秒 await new Promise(resolve => setTimeout(resolve, 100)); yield 2; // yield 2 等待 100 毫秒 await new Promise(resolve => setTimeout(resolve, 100)); yield 3; // yield 3 不等待 } const asyncIter = asyncGenerator(); asyncIter.next() .then(value => { console.log(value); // { value: 1, done: false } return asyncIter.next(); }).then(value => { console.log(value); // { value: 2, done: false } return asyncIter.next(); }).then(value => { console.log(value); // { value: 3, done: false } return asyncIter.next(); }).then(value => { console.log(value); // { value: undefined, done: true } });
在这个示例中,我们使用了一个异步生成器来生成三个值,每个值之间都有一个 100 毫秒的延迟。通过调用 asyncIter.next()
方法,我们可以一个一个地获取值。需要注意的是,每次调用 next
方法都是一个异步操作,因此我们需要使用 Promise 对象来捕获结果。
for async/of
现在我们已经了解了异步迭代器,让我们来看看 for async/of
语句。for async/of
允许我们循环一个异步迭代器中的值,这个循环体会在每次异步迭代器的 next
方法返回值时执行。
接下来是一个使用 for async/of
语句遍历异步生成器的示例:
// javascriptcn.com 代码示例 async function* asyncGenerator() { yield 1; // yield 1 等待 100 毫秒 await new Promise(resolve => setTimeout(resolve, 100)); yield 2; // yield 2 等待 100 毫秒 await new Promise(resolve => setTimeout(resolve, 100)); yield 3; // yield 3 不等待 } (async () => { for await (const value of asyncGenerator()) { console.log(value); // 1 2 3 } })();
在这个示例中,我们遍历异步生成器返回的值,同时也不需要手动地调用 next
方法,这使我们可以更加方便的编写异步代码。
在实际编程中的应用
现在我们已经了解了 for async/of
,接下来我们将看看这个语句在实际编程中的应用。
异步遍历数组
我们通常会使用 Array.prototype.forEach
来遍历一个数组,但是 forEach
是同步的,当我们需要做一些异步操作时,我们需要并行地遍历数组中的每个元素。这时候,我们可以使用 for async/of
来遍历数组:
// javascriptcn.com 代码示例 const urls = [ 'https://jsonplaceholder.typicode.com/posts/1', 'https://jsonplaceholder.typicode.com/posts/2', 'https://jsonplaceholder.typicode.com/posts/3' ]; async function fetchUrl(url) { const response = await fetch(url); const json = await response.json(); return json; } (async () => { for await (const result of urls.map(fetchUrl)) { console.log(result); } })();
在这个示例中,我们将 urls
数组中每个元素返回的 Promise 对象传递给 fetchUrl
方法中。使用 for async/of
语句,我们可以并行地获取每个请求结果,并输出到控制台中。
异步遍历对象
除了数组,我们同样可以使用 for async/of
来遍历一个对象。
// javascriptcn.com 代码示例 const users = { 1: 'Alice', 2: 'Bob', 3: 'Charlie' }; async function getPermission(user) { const response = await fetch(`https://jsonplaceholder.typicode.com/users/${user}`); const json = await response.json(); return json; } (async () => { for await (const user of Object.keys(users)) { const permission = await getPermission(user); console.log(`${users[user]}: ${permission.name}`); } })();
在这个示例中,我们将 users
对象的 key 作为用户 ID,使用 for async/of
语句并行地获取每个用户的权限信息,并输出到控制台中。
总结
for async/of
语句和异步迭代器(AsyncIterator
)为我们提供了更好的异步编程方案。使用 for async/of
语句,我们可以更加方便地遍历异步迭代器中的值,同时也能够更好地避免回调地狱和过多的 Promise 链式调用。在实际编程中,我们可以将这些功能用于异步遍历数组和对象,来并行地处理异步操作。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654187327d4982a6ebb1de21