Javascript中的迭代器和生成器
Iterator and a Generator in Javascript?
在Mozilla的页面迭代器和生成器上有一条语句:
虽然自定义迭代器是一个有用的工具,但创建它们需要由于需要显式维护内部状态。发电机提供了一种强大的替代方案:您可以通过编写单个函数来定义迭代算法其可以保持其自身的状态。
关于上面的解释,难道不可能在没有生成器的情况下编写一个迭代算法吗,比如:
Array[Symbol.iterator] = function(){
return {
next: function(){
//logic
return {
value: "",
done:false
}
}
}
}
我无法理解。有人能解释一下他们创建替代方案的主要原因吗?对我来说似乎没有太大区别。
它们表面上看起来可能非常相似,但它们的使用方式却截然不同。
迭代程序和迭代程序
迭代器的定义相当严格:它们是包含next
(可能还有其他一些)函数的对象(迭代器)。每次调用next
函数时,都会返回一个具有两个属性的对象:
value
:迭代器的当前值done
:迭代器完成了吗
另一方面,可迭代对象是具有Symbol.iterator
关键字(表示众所周知的符号@@iterator
)的属性的对象。该键包含一个函数,当调用该函数时,它将返回一个新的迭代器。一个可迭代的例子:
const list = {
entries: { 0: 'a', 1: 'b' },
[Symbol.iterator]: function(){
let counter = 0;
const entries = this.entries;
return {
next: function(){
return {
value: entries[counter],
done: !entries.hasOwnProperty(counter++)
}
}
}
}
};
顾名思义,它们的主要目的是提供一个可以迭代的接口:
for (let item of list) { console.log(item); }
// 'a'
// 'b'
发电机
另一方面,发电机的用途要广泛得多。将它们视为可以暂停和恢复的功能会有所帮助。
虽然它们可以迭代(它们的迭代提供了next
方法),但它们可以实现更复杂的过程,并通过next
方法提供输入/输出通信。
一个简单的生成器:
function *mygen () {
var myVal = yield 12;
return myVal * 2;
}
const myIt = mygen();
const firstGenValue = myIt.next().value;
// Generator is paused and yields the first value
const result = myIt.next(firstGenValue * 2).value;
console.log(result); // 48
发电商授权
生成器可以委托给另一个生成器:
function *mydelgen(val) {
yield val * 2;
}
function *mygen () {
var myVal = yield 12;
yield* mydelgen(myVal); // delegate to another generator
}
const myIt = mygen();
const val = myIt.next().value;
console.log(val);
console.log(myIt.next(val).value);
console.log(myIt.next().value);
发电机&承诺
Generators和Promises可以在co.等实用程序的帮助下一起创建一种自动异步迭代器
co(function *(){
// resolve multiple promises in parallel
var a = Promise.resolve(1);
var b = Promise.resolve(2);
var c = Promise.resolve(3);
var res = yield [a, b, c];
console.log(res);
// => [1, 2, 3]
}).catch(onerror);
结论
因此,总之,可以说迭代器的主要目的是为要迭代的自定义对象创建一个接口,而生成器为同步和异步工作流提供了大量的可能性:
- 有状态函数
- 发电机委托
- 发电机&承诺
- CSP
等等。
难道不可能在没有生成器的情况下编写迭代算法吗。
不,不是。是的,可以将每个生成器算法编写为自定义迭代器,但代码中的// logic
会复杂得多。该语句的重点是它不再是迭代的,而是递归的。
作为练习,这里有一个非常简单的迭代生成器函数:
function* traverseTree(node) {
if (node == null) return;
yield* traverseTree(node.left);
yield node.value;
yield* traverseTree(node.right);
}
尝试将其重写为自定义迭代器。无论你是陷入困境还是完成任务,它都会向你展示区别。
- Rails:试图在javascript(Google Charts API)中嵌入一个adv-ruby(each+迭代器
- 在javascript中,从迭代器创建Array
- Javascript中的迭代器和生成器
- javascript中多维数组的迭代器
- Javascript使用for-in循环迭代器来设置变量
- Javascript 替换为 /gi 和数组迭代器
- 如何使用 Javascript 将迭代器索引号附加到数组中的每个项目
- 如何将 Struts 2 中的迭代器列表传递给 JavaScript
- 将自定义迭代器添加到 JavaScript 类
- Javascript 对象调用其他对象粉碎迭代器
- PHP 查询数组到 Javascript Google Maps 迭代器
- 如何循环来自生成器的JavaScript迭代器
- Javascript-如何在带有回调的for循环中使用迭代器
- javascript for..迭代器之谜
- 如何访问Javascript中循环函数的helper中的迭代器
- 如何在JavaScript中创建计数生成器/迭代器级联
- Javascript迭代器建议
- 为什么我们要定义符号.[Symbol]的迭代器.迭代器)?javascript中的可迭代对象
- 如何从迭代器本地链接JavaScript方法
- 迭代器中..的Javascript原型