Si je dois appeler 3 API http dans un ordre séquentiel, quelle serait une meilleure alternative au code suivant:
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
la source
la source
sync-request
bibliothèque, ce qui est une bonne réponse au titre de cette question, mais pas une réponse à ce que le code de la question implique. La réponse ci-dessous à propos des promesses est une meilleure réponse pour cela. Que vouliez-vous dire?Réponses:
Utilisation de différés comme
Futures
.Si vous avez besoin de passer la portée, faites quelque chose comme ça
la source
J'aime aussi la solution de Raynos, mais je préfère une bibliothèque de contrôle de flux différente.
https://github.com/caolan/async
Selon que vous avez besoin des résultats dans chaque fonction suivante, j'utiliserais des séries, des parallèles ou des cascade.
Séries lorsqu'elles doivent être exécutées en série, mais vous n'avez pas nécessairement besoin des résultats à chaque appel de fonction suivant.
Parallèles s'ils peuvent être exécutés en parallèle, vous n'avez pas besoin des résultats de chacun pendant chaque fonction parallèle, et vous avez besoin d'un rappel lorsque tout est terminé.
Cascade si vous souhaitez transformer les résultats de chaque fonction et passer à la suivante
la source
Vous pouvez le faire en utilisant ma bibliothèque Common Node :
la source
require(...).HttpClient is not a constructor
demande de synchronisation
De loin, le plus simple que j'ai trouvé et utilisé est la demande de synchronisation et il prend en charge à la fois le nœud et le navigateur!
C'est tout, pas de configuration folle, pas d'installation de bibliothèques complexes, bien qu'il y ait une bibliothèque de secours. Fonctionne juste. J'ai essayé d'autres exemples ici et j'étais perplexe quand il y avait beaucoup de configuration supplémentaire à faire ou que les installations ne fonctionnaient pas!
Remarques:
L'exemple utilisé par sync-request ne joue pas bien lorsque vous l'utilisez
res.getBody()
, tout ce que fait get body est d'accepter un encodage et de convertir les données de réponse. Faites simplement à lares.body.toString(encoding)
place.la source
J'utiliserais une fonction récursive avec une liste d'apis
modifier: demander la version
edit: demande / version asynchrone
la source
Il semble que les solutions à ce problème soient sans fin, en voici une de plus :)
http://alexeypetrushin.github.com/synchronize
la source
Une autre possibilité est de configurer un rappel qui suit les tâches terminées:
Ensuite, attribuez simplement un ID à chacun et vous pouvez définir vos exigences pour les tâches à effectuer avant de fermer la connexion.
D'accord, ce n'est pas joli. C'est juste une autre façon de passer des appels séquentiels. Il est regrettable que NodeJS ne fournisse pas les appels synchrones les plus élémentaires. Mais je comprends ce qu'est l'attrait de l'asynchronicité.
la source
utilisez sequenty.
sudo npm installer sequenty
ou
https://github.com/AndyShin/sequenty
très simple.
vous pouvez également utiliser une boucle comme celle-ci:
la source
L'utilisation de la bibliothèque de requêtes peut aider à minimiser la cruauté:
Mais pour un maximum de génialité, vous devriez essayer une bibliothèque de flux de contrôle comme Step - cela vous permettra également de paralléliser les requêtes, en supposant que cela soit acceptable:
la source
À partir de 2018 et en utilisant les modules ES6 et les promesses, nous pouvons écrire une fonction comme celle-ci:
puis dans un autre module
Le code doit être exécuté dans un contexte asynchrone (à l'aide d'un
async
mot-clé)la source
Il y a beaucoup de bibliothèques de flux de contrôle - j'aime conseq (... parce que je l'ai écrit.) En outre,
on('data')
peut se déclencher plusieurs fois, alors utilisez une bibliothèque de wrapper REST comme restler .la source
Cela a été bien répondu par Raynos. Pourtant, il y a eu des changements dans la bibliothèque de séquences depuis que la réponse a été publiée.
Pour faire fonctionner la séquence, suivez ce lien: https://github.com/FuturesJS/sequence/tree/9daf0000289954b85c0925119821752fbfb3521e .
Voici comment vous pouvez le faire fonctionner après
npm install sequence
:la source
Voici ma version de @ andy-shin séquentiellement avec des arguments dans le tableau au lieu de l'index:
la source
...4 ans plus tard...
Voici une solution originale avec le framework Danf (vous n'avez besoin d'aucun code pour ce genre de choses, seulement quelques config):
Si vous souhaitez être encore plus court, vous pouvez utiliser un processus de collecte:
Jetez un œil à l' aperçu du framework pour plus d'informations.
la source
J'ai atterri ici parce que j'avais besoin de limiter le taux de http.request (~ 10k requêtes d'agrégation à la recherche élastique pour créer un rapport analytique). Ce qui suit vient d'étouffer ma machine.
Mes URL sont très simples, donc cela ne s'applique peut-être pas de manière triviale à la question originale, mais je pense que c'est à la fois potentiellement applicable et vaut la peine d'être écrit ici pour les lecteurs qui débarquent ici avec des problèmes similaires aux miens et qui veulent une solution JavaScript triviale sans bibliothèque.
Mon travail ne dépendait pas de l'ordre et ma première approche pour éviter cela était de l'envelopper dans un script shell pour le fragmenter (car je suis nouveau dans JavaScript). C'était fonctionnel mais pas satisfaisant. Ma résolution JavaScript à la fin était de faire ce qui suit:
Cela ressemble à une récursivité mutuelle entre collect et get_top . Je ne suis pas sûr que ce soit en vigueur car le système est asynchrone et la fonction collect se termine par un rappel caché pour l'événement à on. ('End' .
Je pense que c'est assez général pour s'appliquer à la question initiale. Si, comme mon scénario, la séquence / l'ensemble est connu, toutes les URL / clés peuvent être poussées sur la pile en une seule étape. S'ils sont calculés au fur et à mesure, la fonction on ('end' peut pousser l'URL suivante sur la pile juste avant get_top () . Si quoi que ce soit, le résultat a moins d'imbrication et peut être plus facile à refactoriser lorsque l'API que vous appelez changements.
Je me rends compte que c'est effectivement équivalent à la version récursive simple de @ generalhenry ci-dessus (donc j'ai voté pour ça!)
la source
Super demande
Il s'agit d'un autre module synchrone basé sur la demande et utilisant les promesses. Super simple à utiliser, fonctionne bien avec les tests de moka.
npm install super-request
la source
Ce code peut être utilisé pour exécuter un tableau de promesses de manière synchrone et séquentielle, après quoi vous pouvez exécuter votre code final dans l'
.then()
appel.la source
En fait, j'ai eu exactement ce que vous (et moi) vouliez, sans l'utilisation de await, Promises ou inclusions de toute bibliothèque (externe) (sauf la nôtre).
Voici comment procéder:
Nous allons créer un module C ++ pour aller avec node.js, et cette fonction de module C ++ effectuera la requête HTTP et retournera les données sous forme de chaîne, et vous pouvez l'utiliser directement en faisant:
ÊTES-VOUS PRÊT à commencer?
Étape 1: créez un nouveau dossier ailleurs sur votre ordinateur, nous n'utilisons ce dossier que pour construire le fichier module.node (compilé à partir de C ++), vous pourrez le déplacer plus tard.
Dans le nouveau dossier (j'ai mis le mien dans mynewFolder / src pour organiser-ness):
puis
créez maintenant 2 nouveaux fichiers: 1, appelé something.cpp et pour mettre ce code dedans (ou modifiez-le si vous le souhaitez):
Maintenant, créez un nouveau fichier dans le même répertoire appelé
something.gyp
et mettez-y (quelque chose comme) ceci:Maintenant, dans le fichier package.json, ajoutez:
"gypfile": true,
Maintenant: dans la console,
node-gyp rebuild
S'il passe par toute la commande et dit "ok" à la fin sans erreur, vous êtes (presque) prêt à partir, sinon, laissez un commentaire.
Mais si cela fonctionne, allez dans build / Release / cobypp.node (ou quel que soit son nom), copiez-le dans votre dossier principal node.js, puis dans node.js:
la source