Sie können auf der Oberfläche sehr ähnlich aussehen, aber sie können auf sehr unterschiedliche Weise verwendet werden.
Iteratoren und Iterables
Iteratoren sind ziemlich streng definiert: sie sind Gegenstand (den Iteratoren), die enthält eine next
(und möglicherweise einige andere) -Funktion. Jedes Mal, wenn die next
Funktion aufgerufen wird, wird erwartet, ein Objekt mit zwei Eigenschaften zurück:
value
: der aktuelle Wert des Iterators
done
: ist der Iterator fertig?
Ein iterable auf der anderen Seite ist ein Objekt, das eine Eigenschaft mit einem Symbol.iterator
Schlüssel hat (das das Symbol gut kennen darstellt @@iterator
). Dieser Schlüssel enthält eine Funktion, die beim Aufruf einen neuen Iterator zurückgibt. Ein Beispiel für eine iterable:
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++)
}
}
}
}
};
Ihr Hauptzweck, wie ihr Name schon sagt, ist eine Schnittstelle zu schaffen, die durchlaufen werden können:
for (let item of list) { console.log(item); }
// 'a'
// 'b'
Generatoren
Generatoren auf die Andererseits sind sie vielseitiger. Es hilft, sie als Funktionen zu betrachten, die pausiert und wieder aufgenommen werden können.
Während sie iteriert werden können (ihre iterables bieten eine next
Methode), können sie viel kompliziertere Verfahren implementieren und eine Eingabe/Ausgabe-Kommunikation über ihre next
Methode bereitstellen.
Ein einfacher Generator:
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
Generator Delegation
Generatoren an einen anderen Generator delegieren kann:
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);
Generatoren & Promises
Generatoren und Promises können zusammen mit Hilfe von Dienstprogrammen wie co eine Art automatischen asynchronen Iterator erstellen.
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);
Im Fazit
Also abschließend könnte man sagen, dass der Hauptzweck der Iteratoren ist eine Schnittstelle zu schaffen für benutzerdefinierte Objekte iteriert werden, während Generatoren eine Fülle von Möglichkeiten für die synchronen bieten und asynchronen Workflows:
- Stateful Funktionen
- Generator Delegation
- Generatoren &
- CSP
usw.
'next': ist die Iterationsfunktion für jede Variable im Array. –
Ich empfehle "syntaktischen Zucker" googeln. – zzzzBov
@zzzzBov, in angular2 '#' Charakter ist ein syntaktischer Zucker, aber in seinem Fall glaube ich nicht, – serkan