Si necesito llamar a 3 API http en orden secuencial, ¿cuál sería una mejor alternativa al siguiente código?
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
fuente
fuente
sync-request
biblioteca, que es una buena respuesta al título de esta pregunta, pero no una respuesta a lo que implica el código de la pregunta. La respuesta a continuación sobre Promesas es una mejor respuesta para eso. ¿A qué te refieres?Respuestas:
Usando diferidos como
Futures
.Si necesita pasar el alcance, haga algo como esto
fuente
También me gusta la solución de Raynos, pero prefiero una biblioteca de control de flujo diferente.
https://github.com/caolan/async
Dependiendo de si necesita los resultados en cada función posterior, usaría serie, paralelo o cascada.
Series cuando deben ejecutarse en serie, pero no necesariamente necesita los resultados en cada llamada de función posterior.
Paralelo, si se pueden ejecutar en paralelo, no necesita los resultados de cada uno durante cada función en paralelo, y necesita una devolución de llamada cuando todas se hayan completado.
Cascada si desea transformar los resultados en cada función y pasar a la siguiente
fuente
Puede hacer esto usando mi biblioteca de nodo común :
fuente
require(...).HttpClient is not a constructor
solicitud de sincronización
Con mucho, el más fácil que he encontrado y utilizado es la solicitud de sincronización y es compatible con el nodo y el navegador.
Eso es todo, sin configuración loca, sin instalaciones de lib complejas, aunque tiene un respaldo de lib. Simplemente funciona. ¡He probado otros ejemplos aquí y me quedé perplejo cuando había mucha configuración adicional por hacer o las instalaciones no funcionaron!
Notas:
El ejemplo que usa la solicitud de sincronización no funciona bien cuando lo usa
res.getBody()
, todo lo que hace get body es aceptar una codificación y convertir los datos de respuesta. Solo hazlo en sures.body.toString(encoding)
lugar.fuente
Usaría una función recursiva con una lista de apis
editar: solicitar versión
editar: solicitud / versión asincrónica
fuente
Parece que las soluciones para este problema no tienen fin, aquí hay una más :)
http://alexeypetrushin.github.com/synchronize
fuente
Otra posibilidad es configurar una devolución de llamada que rastrea las tareas completadas:
Luego, simplemente asigne una ID a cada uno y podrá configurar sus requisitos para qué tareas deben completarse antes de cerrar la conexión.
Está bien, no es bonito. Es solo otra forma de realizar llamadas secuenciales. Es lamentable que NodeJS no proporcione las llamadas sincrónicas más básicas. Pero entiendo cuál es el atractivo de la asincronía.
fuente
use sequenty.
sudo npm install sequenty
o
https://github.com/AndyShin/sequenty
muy simple.
también puedes usar un bucle como este:
fuente
El uso de la biblioteca de solicitudes puede ayudar a minimizar el problema:
Pero para una máxima genialidad, debería probar alguna biblioteca de flujo de control como Step; también le permitirá paralelizar las solicitudes, asumiendo que es aceptable:
fuente
A partir de 2018 y usando los módulos ES6 y Promesas, podemos escribir una función como esa:
y luego en otro módulo
El código debe ejecutarse en un contexto asincrónico (usando una
async
palabra clave)fuente
Hay muchas bibliotecas de flujo de control: me gusta conseq (... porque lo escribí). Además,
on('data')
puede dispararse varias veces, así que use una biblioteca de envoltura REST como restler .fuente
Esto ha sido bien respondido por Raynos. Sin embargo, ha habido cambios en la biblioteca de secuencias desde que se publicó la respuesta.
Para que la secuencia funcione, siga este enlace: https://github.com/FuturesJS/sequence/tree/9daf0000289954b85c0925119821752fbfb3521e .
Así es como puede hacer que funcione después
npm install sequence
:fuente
Aquí está mi versión de @ andy-shin secuencialmente con argumentos en matriz en lugar de índice:
fuente
...4 años después...
Aquí hay una solución original con el framework Danf (no necesitas ningún código para este tipo de cosas, solo algunas configuraciones):
Si desea ser aún más corto, puede usar un proceso de recolección:
Eche un vistazo a la descripción general del marco para obtener más información.
fuente
Aterricé aquí porque necesitaba limitar la tasa de http.request (~ 10k consultas de agregación a la búsqueda elástica para crear un informe analítico). Lo siguiente acaba de ahogar mi máquina.
Mis URL son muy simples, por lo que es posible que esto no se aplique trivialmente a la pregunta original, pero creo que es potencialmente aplicable y vale la pena escribirlo aquí para los lectores que aterrizan aquí con problemas similares al mío y que desean una solución trivial sin biblioteca de JavaScript.
Mi trabajo no dependía del pedido y mi primer enfoque para hacer esto fue envolverlo en un script de shell para dividirlo (porque soy nuevo en JavaScript). Eso fue funcional pero no satisfactorio. Mi resolución de JavaScript al final fue hacer lo siguiente:
Parece una recursividad mutua entre collect y get_top . No estoy seguro de que esté en efecto porque el sistema es asincrónico y la función recopilar se completa con una devolución de llamada guardada para el evento en el. ('End' .
Creo que es lo suficientemente general como para aplicarse a la pregunta original. Si, como en mi escenario, se conoce la secuencia / conjunto, todas las URL / claves se pueden insertar en la pila en un solo paso. Si se calculan sobre la marcha , la función on ('end' puede enviar la siguiente URL en la pila justo antes de get_top () . En todo caso, el resultado tiene menos anidamiento y podría ser más fácil de refactorizar cuando la API que está llamando cambios.
Me doy cuenta de que esto es efectivamente equivalente a la versión recursiva simple de @ generalhenry anterior (¡así que voté a favor de eso!)
fuente
Super solicitud
Este es otro módulo síncrono que se basa en una solicitud y utiliza promesas. Súper simple de usar, funciona bien con pruebas de moca.
npm install super-request
fuente
Este código se puede utilizar para ejecutar una serie de promesas de forma sincrónica y secuencial, después de lo cual puede ejecutar su código final en la
.then()
llamada.fuente
De hecho, obtuve exactamente lo que tú (y yo) queríamos, sin el uso de await, Promises o inclusiones de ninguna biblioteca (externa) (excepto la nuestra).
He aquí cómo hacerlo:
Vamos a crear un módulo C ++ que vaya con node.js, y esa función del módulo C ++ hará la solicitud HTTP y devolverá los datos como una cadena, y puede usar eso directamente haciendo:
¿ESTÁS LISTO para empezar?
Paso 1: cree una nueva carpeta en otro lugar de su computadora, solo estamos usando esta carpeta para construir el archivo module.node (compilado desde C ++), puede moverlo más tarde.
En la nueva carpeta (puse la mía en mynewFolder / src para organizar-ness):
luego
ahora cree 2 archivos nuevos: 1, llamado something.cpp y para poner este código en él (o modificarlo si lo desea):
Ahora cree un nuevo archivo en el mismo directorio llamado
something.gyp
y coloque (algo como) esto en él:Ahora en el archivo package.json, agregue:
"gypfile": true,
Ahora: en la consola,
node-gyp rebuild
Si pasa por todo el comando y dice "ok" al final sin errores, está (casi) listo, si no, deje un comentario.
Pero si funciona, vaya a build / Release / cobypp.node (o lo que sea que le llame), cópielo en su carpeta principal node.js, luego en node.js:
fuente