Ich bin auf der Suche nach einem RxJS-Beispiel, wie eine Reihe von XHR-Aufrufe (oder andere asynchrone Operationen) zwischengespeichert werden, so dass derselbe Aufruf nicht wiederholt werden muss Unveränderlichkeit und ohne Nebenwirkungen.RxJS: Cache Mehrere XHR-Aufrufe ohne Mutabilität und Nebenwirkungen
Hier ist ein nackten Knochen, wandelbar Beispiel:
var dictionary = {}; // mutable
var click$ = Rx.Observable.fromEvent(document.querySelector('button'), 'click', function (evt) {
return Math.floor(Math.random() * 6) + 1; // click -> random number 1-6 (key)
})
.flatMap(getDefinition);
var clicksub = click$.subscribe(function (key) {
console.log(key);
});
function getDefinition (key) {
if (dictionary[key]) { // check dict. for key
console.log('from dictionary');
return Rx.Observable.return(dictionary[key]);
}
// key not found, mock up async operation, to be replaced with XHR
return Rx.Observable.fromCallback(function (key, cb) {
dictionary[key] = key; // side effect
cb(dictionary[key); // return definition
})(key);
}
Frage: Gibt es eine Möglichkeit zur Verwendung des dictionary
Variable ohne Rückgriff Cachen mehr ähnlichen Asynchron-Operationen zu erreichen, aufgrund Wandelbarkeit und Nebenwirkung?
Ich habe bei scan
als Mittel sieht die XHR Anruf Ergebnisse zu „sammeln“, aber ich sehe nicht, wie ein asynchronen Betrieb innerhalb Scan zu handhaben.
Ich denke, ich habe hier zwei Probleme: ein Zustand wird vom Ereignisstrom verwaltet und nicht in einer Variablen gespeichert, und der zweite enthält eine bedingte Operation, die möglicherweise von einer asynchronen Operation abhängt Stromfluss.
Ich bekomme einen Fehler mit "Defer", aber "vonPromise" (in Verbindung mit einem XHR-Aufruf, der eine Zusage zurückgibt) übergibt den abgerufenen Wert im Stream. Allerdings bleibt das Problem bestehen, wie der abgerufene Wert aus der asynchronen Operation (Versprechen, XHR ...) in den Cache abgerufen werden kann. Das Hinzufügen des Schlüssels zum Cache, wie in Ihrer Antwort, speichert den abgerufenen Wert nicht für die zukünftige Verwendung. – bloodyKnuckles
hat den Code aktualisiert. Was ist es, das nicht mit Defer funktioniert? Meine Vermutung ist, dass die als Parameter übergebene Funktion ein Observable zurückgeben muss und ein Versprechen abgegeben hat. Es sollte jetzt funktionieren. Die wichtigsten Einsichten sind in jedem Fall drei: 1. Die Ausführung in eine Funktion umbrechen (d. H. Die Ausführung des Aufrufs verzögern). 2. Den Stream als Teil des Zustands übergeben. 3. Mit "concatAll" Ergebnisse in der richtigen Reihenfolge erhalten. Über Insight 1 könnten Sie den Aufruf direkt ausführen, aber dann führen Sie einen Nebeneffekt innerhalb des "Scan" aus. Nichts ist falsch daran, aber ich bevorzuge eine reine Funktion in der "Scan". – user3743222
Das hilft sehr. Frage, was ist der Zweck von "Aufschub"? Ich habe es herausgezogen (und brachte "fromPromise" nach vorne) und das Caching funktioniert wie gewünscht (siehe meine aktualisierte Antwort). – bloodyKnuckles