Angenommen, Sie verwalten eine Bibliothek, die eine Funktion verfügbar macht getData
. Ihre Benutzer rufen es auf, um aktuelle Daten abzurufen:
var output = getData();
Unter der Haube werden Daten in einer Datei gespeichert, sodass Sie sie getData
mit Node.js integriert implementieren fs.readFileSync
. Es ist beides offensichtlich getData
und fs.readFileSync
es handelt sich um Synchronisierungsfunktionen. Eines Tages wurde Ihnen gesagt, dass Sie die zugrunde liegende Datenquelle auf ein Repo wie MongoDB umstellen sollen, auf das nur asynchron zugegriffen werden kann. Sie wurden auch angewiesen, Ihre Benutzer getData
nicht zu verärgern. Die API kann nicht geändert werden, um lediglich ein Versprechen zurückzugeben oder einen Rückrufparameter zu fordern. Wie erfüllen Sie beide Anforderungen?
Asynchrone Funktion mit Rückruf / Versprechen ist die DNA von JavasSript und Node.js. Jede nicht triviale JS-App ist wahrscheinlich von diesem Codierungsstil durchdrungen. Diese Praxis kann jedoch leicht zu einer sogenannten Rückrufpyramide des Untergangs führen. Schlimmer noch, wenn ein Code in einem Aufrufer in der Aufrufkette vom Ergebnis der asynchronen Funktion abhängt, muss dieser Code ebenfalls in die Rückruffunktion eingeschlossen werden, wodurch dem Anrufer eine Einschränkung des Codierungsstils auferlegt wird. Von Zeit zu Zeit muss eine asynchrone Funktion (die häufig in einer Bibliothek eines Drittanbieters bereitgestellt wird) in eine Synchronisierungsfunktion eingekapselt werden, um ein massives globales Re-Factoring zu vermeiden. Die Suche nach einer Lösung zu diesem Thema endete normalerweise mit Node Fibersoder davon abgeleitete npm-Pakete. Aber Fasern können das Problem, mit dem ich konfrontiert bin, einfach nicht lösen. Sogar das Beispiel des Autors von Fibers illustrierte den Mangel:
...
Fiber(function() {
console.log('wait... ' + new Date);
sleep(1000);
console.log('ok... ' + new Date);
}).run();
console.log('back in main');
Tatsächliche Ausgabe:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
Wenn die Funktion Fibre den asynchronen Funktionsschlaf wirklich synchronisiert, sollte die Ausgabe wie folgt lauten:
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
back in main
Ich habe ein weiteres einfaches Beispiel in JSFiddle erstellt und nach Code gesucht, um die erwartete Ausgabe zu erzielen. Ich akzeptiere eine Lösung, die nur in Node.js funktioniert, sodass Sie jedes npm-Paket benötigen können, obwohl Sie nicht in JSFiddle arbeiten.