是否存在您自己手动实现迭代器的用例



iterator经常被使用,例如在spread运算符、for/of-循环、解构等中。但它们是隐藏的。我想知道是否存在您会积极使用如何实现迭代器的知识的用例?

例如,使用迭代器对数组进行迭代过于复杂,如下所示,我不知道为什么有人会自己实现迭代器:

function arrayIterable(arr = []) {
let index = 0;
const len = arr.length;
const arrayIterator = {
next: () => {
let result;
if (index === len) {
return { value: arr[index], done: true };            
}
result = { value: arr[index], done: false }
index++;
return result;           
}
};
return arrayIterator;
}
const myArr = ['a','b','c','d'];
let iter = arrayIterator(myArr);
let result = iter.next();
while (!result.done) {
console.log(result.value);
result = iter.next();
}

如果您想在数据集上懒散地操作,这很方便。一个流、一个文件、一个数据库,您可以从一行/记录移动到另一行,并推进迭代器。没有必要把历史留在记忆中。

由于不必在内存中维护整个源,因此还可以处理无限数据源的情况。

迭代器最大的优势是在客户端。在预迭代器时代的代码中,通常会给您一个类似数组的对象来公开索引。然而,在现代代码中,可以为您提供迭代器,这意味着客户端使用相同的代码处理更一般的结果。请参阅此问题下的讨论以获取示例案例。

我不认为它是如何实现的知识会被用来实际迭代。与使用for of循环相比,这没有任何优势。

但假设您正在构建一个JavaScript库,例如MongoDB数据库的Node.js驱动程序。您希望使查询数据库和循环结果变得容易。你实现了可迭代的协议,然后人们就可以这样做:

const cursor = queryDatabase(<some query>)
for (let doc of cursor) {
// do something with doc
}

事实上,MongoDB驱动程序确实做到了这一点(除了它们实现了异步迭代器(。

EDIT:注意使用迭代器协议相对于从queryDatabase()返回类似数组的对象的好处。特别是在MongoDB中,cursor并不能保存所有的结果。它是一个句柄,通过调用cursor.next()可以获得查询结果

正如您在问题中指出的,必须调用cursor.next()的问题在于它相当笨重。然而,这是好的,因为并非所有的结果都需要从数据库中提取,数据库中可能有数千个。因此,迭代器协议是一种保持cursor.next()优点的方法,而不必处理丑陋的语法。

您可以在MDN:上找到JavaScript中迭代器技术的全面介绍

请参阅MDN:迭代协议

它还包含应用领域、用法和示例。

最新更新