Wenn ich 3 http API in sequentieller Reihenfolge aufrufen muss, was wäre eine bessere Alternative zum folgenden Code:
http.get({ host: 'www.example.com', path: '/api_1.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_2.php' }, function(res) {
res.on('data', function(d) {
http.get({ host: 'www.example.com', path: '/api_3.php' }, function(res) {
res.on('data', function(d) {
});
});
}
});
});
}
});
});
}
node.js
synchronization
Howard
quelle
quelle
sync-request
Bibliothek erwähnt wird. Dies ist eine gute Antwort auf den Titel dieser Frage, aber keine Antwort darauf, was der Code der Frage impliziert. Die Antwort unten über Versprechen ist eine bessere Antwort darauf. Was hast du gemeint?Antworten:
Verwenden Sie aufgeschobene wie
Futures
.Wenn Sie den Bereich weitergeben müssen, tun Sie einfach so etwas
quelle
Ich mag auch die Lösung von Raynos, aber ich bevorzuge eine andere Flusskontrollbibliothek.
https://github.com/caolan/async
Je nachdem, ob Sie die Ergebnisse für jede nachfolgende Funktion benötigen, würde ich entweder Serien, Parallel oder Wasserfall verwenden.
Serien, wenn sie seriell ausgeführt werden müssen, Sie aber nicht unbedingt die Ergebnisse in jedem nachfolgenden Funktionsaufruf benötigen.
Parallel, wenn sie parallel ausgeführt werden können, benötigen Sie nicht die Ergebnisse von jeder während jeder parallelen Funktion, und Sie benötigen einen Rückruf, wenn alle abgeschlossen sind.
Wasserfall, wenn Sie die Ergebnisse in jeder Funktion ändern und zur nächsten übergehen möchten
quelle
Sie können dies mit meiner Common Node-Bibliothek tun :
quelle
require(...).HttpClient is not a constructor
Sync-Anfrage
Die mit Abstand einfachste, die ich gefunden und verwendet habe, ist die Synchronisierungsanforderung , die sowohl den Knoten als auch den Browser unterstützt!
Das war's, keine verrückte Konfiguration, keine komplexe lib-Installation, obwohl es einen lib-Fallback gibt. Funktioniert einfach. Ich habe hier andere Beispiele ausprobiert und war ratlos, als es viel mehr Setup gab oder Installationen nicht funktionierten!
Anmerkungen:
Das Beispiel, das die Synchronisierungsanforderung verwendet, spielt sich bei der Verwendung nicht gut ab
res.getBody()
. Get body akzeptiert lediglich eine Codierung und konvertiert die Antwortdaten. Mach es einfachres.body.toString(encoding)
stattdessen.quelle
Ich würde eine rekursive Funktion mit einer Liste von Apis verwenden
bearbeiten: Version anfordern
edit: request / async version
quelle
Es scheint, dass Lösungen für dieses Problem niemals enden, hier noch eine :)
http://alexeypetrushin.github.com/synchronize
quelle
Eine andere Möglichkeit besteht darin, einen Rückruf einzurichten, der erledigte Aufgaben verfolgt:
Weisen Sie dann einfach jedem eine ID zu, und Sie können Ihre Anforderungen festlegen, für die Aufgaben ausgeführt werden müssen, bevor die Verbindung geschlossen wird.
Okay, es ist nicht schön. Es ist nur eine andere Möglichkeit, sequentielle Anrufe zu tätigen. Es ist bedauerlich, dass NodeJS nicht die grundlegendsten synchronen Anrufe bereitstellt. Aber ich verstehe, was der Reiz zur Asynchronität ist.
quelle
benutze sequenty.
sudo npm install sequenty
oder
https://github.com/AndyShin/sequenty
sehr einfach.
Sie können auch eine Schleife wie diese verwenden:
quelle
Die Verwendung der Anforderungsbibliothek kann dazu beitragen, die Cruft zu minimieren:
Für maximale Attraktivität sollten Sie jedoch eine Kontrollflussbibliothek wie Step ausprobieren. Sie können damit auch Anforderungen parallelisieren, sofern dies akzeptabel ist:
quelle
Ab 2018 können wir mit ES6-Modulen und Promises eine solche Funktion schreiben:
und dann in einem anderen Modul
Der Code muss in einem asynchronen Kontext ausgeführt werden (mit
async
Schlüsselwort)quelle
Es gibt viele Kontrollflussbibliotheken - ich mag conseq (... weil ich es geschrieben habe).
on('data')
Kann auch mehrmals ausgelöst werden , verwenden Sie also eine REST-Wrapper-Bibliothek wie restler .quelle
Dies wurde von Raynos gut beantwortet. In der Sequenzbibliothek wurden jedoch Änderungen vorgenommen, seit die Antwort veröffentlicht wurde.
Folgen Sie diesem Link, um die Sequenz zum Laufen zu bringen: https://github.com/FuturesJS/sequence/tree/9daf0000289954b85c0925119821752fbfb3521e .
So können Sie es zum Laufen bringen
npm install sequence
:quelle
Hier ist meine Version von @ andy-shin nacheinander mit Argumenten im Array anstelle des Index:
quelle
...4 Jahre später...
Hier ist eine originelle Lösung mit dem Framework Danf (Sie benötigen keinen Code für diese Art von Dingen, nur einige Konfigurationen):
Wenn Sie noch kürzer sein möchten, können Sie einen Erfassungsprozess verwenden:
Weitere Informationen finden Sie in der Übersicht des Frameworks.
quelle
Ich bin hier gelandet, weil ich http.request einschränken musste (~ 10.000 Aggregationsabfragen zur elastischen Suche, um einen Analysebericht zu erstellen). Das Folgende hat gerade meine Maschine erstickt.
Meine URLs sind sehr einfach, so dass dies möglicherweise nicht trivial auf die ursprüngliche Frage zutrifft, aber ich denke, es ist potenziell anwendbar und es lohnt sich, hier für Leser zu schreiben, die hier mit ähnlichen Problemen wie ich landen und eine triviale JavaScript-Lösung ohne Bibliothek wünschen.
Mein Job war nicht auftragsabhängig und mein erster Ansatz war, ihn in ein Shell-Skript zu packen, um ihn zu zerlegen (weil ich neu in JavaScript bin). Das war funktionell aber nicht zufriedenstellend. Meine JavaScript-Auflösung bestand am Ende darin, Folgendes zu tun:
Es sieht aus wie eine gegenseitige Rekursion zwischen collect und get_top . Ich bin nicht sicher , ist es in der Tat , da das System asynchron ist und die Funktion Collect schließt mit einem Rückruf für den Fall , verstaute bei auf. ( ‚Ende‘ .
Ich denke, es ist allgemein genug, um auf die ursprüngliche Frage anzuwenden. Wenn wie in meinem Szenario die Reihenfolge / Menge bekannt ist, können alle URLs / Schlüssel in einem Schritt auf den Stapel verschoben werden. Wenn sie im Laufe der Zeit berechnet werden, kann die Funktion on ('end' die nächste URL auf dem Stapel kurz vor get_top () verschieben . Wenn überhaupt, ist das Ergebnis weniger verschachtelt und kann möglicherweise einfacher umgestaltet werden, wenn die API aufgerufen wird Änderungen.
Mir ist klar, dass dies effektiv der einfachen rekursiven Version von @ generalhenry oben entspricht (also habe ich das positiv bewertet!)
quelle
Super Anfrage
Dies ist ein weiteres synchrones Modul, das auf Anfrage basiert und Versprechen verwendet. Super einfach zu bedienen, funktioniert gut mit Mokka-Tests.
npm install super-request
quelle
Dieser Code kann verwendet werden, um eine Reihe von Versprechungen synchron und nacheinander auszuführen, wonach Sie Ihren endgültigen Code im
.then()
Aufruf ausführen können .quelle
Ich habe genau das bekommen, was Sie (und ich) wollten, ohne Wartezeiten, Versprechen oder Einschlüsse einer (externen) Bibliothek (außer unserer eigenen).
So geht's:
Wir werden ein C ++ - Modul erstellen, das zu node.js passt, und diese C ++ - Modulfunktion wird die HTTP-Anforderung stellen und die Daten als Zeichenfolge zurückgeben. Sie können dies direkt verwenden, indem Sie Folgendes tun:
SIND SIE BEREIT , loszulegen?
Schritt 1: Erstellen Sie einen neuen Ordner an einer anderen Stelle auf Ihrem Computer. Wir verwenden diesen Ordner nur zum Erstellen der Datei module.node (kompiliert aus C ++). Sie können sie später verschieben.
In dem neuen Ordner (ich habe meinen in mynewFolder / src für die Organisation abgelegt):
dann
Jetzt mache 2 neue Dateien: 1, etwas.cpp genannt und füge diesen Code ein (oder ändere ihn, wenn du willst):
Erstellen Sie nun eine neue Datei im selben Verzeichnis mit dem Namen
something.gyp
und legen Sie (so etwas) darin ab:Fügen Sie nun in der Datei package.json Folgendes hinzu:
"gypfile": true,
Jetzt: in der Konsole,
node-gyp rebuild
Wenn es den gesamten Befehl durchläuft und am Ende fehlerfrei "ok" sagt, können Sie (fast) loslegen. Wenn nicht, hinterlassen Sie einen Kommentar.
Wenn es funktioniert, gehen Sie zu build / Release / cobypp.node (oder wie auch immer es für Sie heißt), kopieren Sie es in Ihren Hauptordner node.js und dann in node.js:
quelle