近年来,随着前端应用的复杂性不断提升,处理数据流成为了前端开发中的一个核心问题。而在 ES2018 中引入的 async iterator 和 for await of 新特性,为前端开发中的数据流处理提供了全新的解决方案。
async iterator
在以往的 JavaScript 中,我们通过 for..of 循环来遍历迭代器中的元素。而在 ES2018 中,为了支持异步数据流处理,引入了 async iterator。这一概念可以理解为一个支持异步操作的迭代器。
下面是一个 async iterator 的例子:
// www.javascriptcn.com code example
async function iterateUserNames() {
const users = ['Alice', 'Bob', 'Charlie'];
for (const user of users) {
await new Promise((resolve) => setTimeout(resolve, 1000));
yield user;
}
}
(async () => {
const iterator = iterateUserNames();
console.log(await iterator.next()); // { value: 'Alice', done: false }
console.log(await iterator.next()); // { value: 'Bob', done: false }
console.log(await iterator.next()); // { value: 'Charlie', done: false }
console.log(await iterator.next()); // { value: undefined, done: true }
})();通过 async function 和 yield 实现了异步迭代器,并通过 await iterator.next() 来获取每一次迭代的值。
for await of
而对于异步迭代器的遍历,可以使用 for await of 循环。这个循环会在每次迭代中暂停,等待 Promise 的解析结果。
下面是一个使用 for await of 的例子:
// www.javascriptcn.com code example
async function readLines(path) {
const readableStream = fs.createReadStream(path);
const rl = readline.createInterface({ input: readableStream });
for await (const line of rl) {
console.log(line);
}
}
readLines('/path/to/file')
.then(() => console.log('Done'))
.catch(console.error);这个例子中,我们使用 Node.js 的 readline 模块逐行读取文件,仅在每次读取到一行数据后才执行 console.log。而使用 for await of 循环,可以在每次读取数据后暂停,防止程序的过度消耗资源。
示例代码
下面是一个综合运用 async iterator 和 for await of 的示例代码,它将一个可读流中的 JSON 数据解析成一个数组:
// www.javascriptcn.com code example
async function parseJSONStream(stream) {
const asyncIterator = stream[Symbol.asyncIterator]();
let done = false, value = null;
const result = [];
do {
({ done, value } = await asyncIterator.next());
if (!done) {
const json = JSON.parse(value);
for (const item of json) {
result.push(item);
}
}
} while (!done);
return result;
}
const stream = createReadableStreamFromJSONLines();
parseJSONStream(stream)
.then(data => console.log(data))
.catch(console.error);在这个代码中,我们通过将可读流的 async iterator 获取到,然后暂停遍历,解析每一条数据并添加到数组中。而利用 for await of 这个异步迭代器,我们避免了在处理大量数据时程序过度消耗资源的情况。
结语
通过使用 ES2018 中的 async iterator 和 for await of,我们可以更加灵活地处理数据流。这些新特性为我们提供了全新的数据处理解决方案,同时也展示了 JavaScript 不断发展的生命力。我们应该在日常开发中尝试使用它们,提升自己的代码能力和开发效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d7d5e7a941bf7134e0660a