在 ES6 中,引入了一种新的遍历数据结构的方法 - 迭代器(Iterator)协议。该协议规定了一个对象必须实现哪些方法,以便使其可被 for...of 循环进行遍历。
在 ES10 中,对迭代器协议进行了一些改动,下面我们一起来看一下这些变化。
迭代器协议的改动
增加了 Symbol.asyncIterator 方法
Symbol.asyncIterator 方法是一种新的标准方法,它用于定义一个异步迭代器。异步迭代器是一种迭代器,它可以处理 Promise 或者其他异步值。
格式如下:
[Symbol.asyncIterator](): AsyncIterator<T>
注意这里使用了 Symbol.asyncIterator 而非 Symbol.iterator。这是因为异步迭代器需要返回一个异步的 Iterator,而不是同步的 Iterator。
迭代器协议和 for...of 循环的自动关闭
在 ES6 中,我们需要手动关闭迭代器,否则会出现一些问题。而在 ES10 中,迭代器协议规定了一个 new CloseableIterator 接口,该接口可被用于自动关闭迭代器。
例如,在 for...of 循环中,当迭代器被完全遍历完毕时,会自动关闭迭代器:
// www.javascriptcn.com code example
async function* asyncGenerator() {
await new Promise(resolve => setTimeout(resolve, 1000));
yield 1;
await new Promise(resolve => setTimeout(resolve, 1000));
yield 2;
await new Promise(resolve => setTimeout(resolve, 1000));
yield 3;
}
(async () => {
for
await (const item of asyncGenerator()) {
console.log(item);
}
})();
// 输出 1 2 3实验示例
为了更好地理解这些改动,下面我们将通过实验来演示它们的使用。
实验一:使用 Symbol.asyncIterator
我们先来看一下,如何使用 Symbol.asyncIterator 方法来定义一个异步迭代器。
在此实验中,我们将创建一个简单的异步迭代器,它可以逐步返回一个数字数组中的所有元素:
// www.javascriptcn.com code example
const myAsyncIterable = {
async* [Symbol.asyncIterator]() {
yield 1;
yield 2;
yield 3;
}
};
(async function() {
for
await (const x of myAsyncIterable) {
console.log(x);
}
})();
// 输出 1 2 3如上所示,在 myAsyncIterable 对象中,我们使用了 Symbol.asyncIterator 方法来定义了一个异步迭代器。使用 async* 可以创建一个异步的生成器函数。
注意,由于我们使用了异步生成器,我们需要在 for...of 循环中使用 await 关键字。
实验二:使用 CloseableIterator 自动关闭迭代器
接下来,我们将使用 CloseableIterator 接口来自动关闭迭代器。
在此实验中,我们先创建一个简单的可迭代对象 myIterable,然后在其中定义了一个迭代器 myIterator。在该迭代器(myIterator)被完全遍历后,我们将自动关闭迭代器:
// www.javascriptcn.com code example
const myIterable = {
[Symbol.iterator]() {
let index = 0;
return {
next() {
if (index < 3) {
index++;
return {value: index, done: false};
} else {
return {value: undefined, done: true};
}
},
return() {
console.log('CloseableIterator closed!');
return {done: true}
}
};
}
};
(async function() {
for
await (const x of myIterable) {
console.log(`x: ${x}`);
}
})();
// 输出 x: 1 x: 2 x: 3 CloseableIterator closed!如上所示,在 myIterable 对象中,我们定义了一个迭代器 myIterator,并在其中定义了一个 return 方法。
在 myIterable 对象被完全遍历后,将自动触发 return 方法,并输出 CloseableIterator closed!。
结语
ES10 中对迭代器协议所做的改动,使得在我们处理异步数据时更加方便快捷。同时,CloseableIterator 接口的使用也让我们可以更加方便地自动关闭迭代器。
如果你正在开发一个异步应用程序或使用迭代器协议进行数据遍历,相信这些新的特性会给你带来很大的帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d7b230a941bf7134dcb99f