Completa node.js principiante aquí. Vi este ejemplo de "hola mundo" en alguna parte

// Load the http module to create an http server.
var http = require('http');

// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello World\n");
});

// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);

// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");

Código realmente simple en el que el servidor responde a las solicitudes HTTP con una respuesta HTTP simple con texto sin formato "Hello World"

También estoy listo sobre una biblioteca para hacer solicitudes HTTP desde JavaScript

http.get(options, function(resp){
  resp.on('data', function(chunk){
    //do something with chunk
  });
}).on("error", function(e){
  console.log("Got error: " + e.message);
});

Aquí realiza una solicitud HTTP con algunas opciones y luego hace algo con la respuesta en una devolución de llamada.

Si se hiciera una solicitud de API de este tipo cuando una solicitud HTTP llega al servidor node.js, ¿qué sucede? Dado que el flujo debe ser de un solo subproceso, ¿cómo se puede cambiar el estado de la respuesta que node.js envía al cliente en la devolución de llamada de la solicitud de API HTTP? ¿No se enviará la respuesta al bucle de eventos para entonces? ¿Cómo se pueden simular solicitudes síncronas en este sistema para que pueda utilizar la respuesta de la solicitud API para enviar una respuesta al cliente?

2
Curious 4 mar. 2017 a las 19:55

2 respuestas

La mejor respuesta

Dado que el flujo debe ser de un solo subproceso, ¿cómo se puede cambiar el estado de la respuesta que envía node.js al cliente en la devolución de llamada de la solicitud de API HTTP?

Porque la respuesta no se envía sincrónicamente con la solicitud que se ha recibido.

¿No se enviará la respuesta al bucle de eventos para entonces?

La respuesta no se envía hasta que llame a res.send o similar, que no tiene que estar en el mismo trabajo desde la cola de trabajos que activó su devolución de llamada de solicitud, y con frecuencia no lo está.

¿Cómo se pueden simular solicitudes síncronas en este sistema para que pueda usar la respuesta de la solicitud de API para enviar una respuesta al cliente?

No hay necesidad de hacerlo, y hacerlo mataría el rendimiento.

En cualquier subproceso dado (y NodeJS usa solo uno), JavaScript funciona sobre la base de una cola de trabajos : el subproceso único de JavaScript funciona recogiendo un trabajo de la cola, ejecutando el código para todo el y luego retomando el siguiente trabajo de la cola (o inactivo hasta que se agregue uno). Cuando entra un evento o similar, si ha configurado un controlador para ese evento, se agrega una llamada a su controlador a la cola de trabajos. (En realidad, hay al menos dos capas en la cola de trabajos; consulte esta respuesta para obtener más información si está interesado. )

Está absolutamente bien si no responde a "Recibimos una solicitud HTTP" dentro del código para el trabajo que llamó a su controlador. Eso es perfectamente normal. El trabajo y la solicitud están completamente disociados entre sí. Y entonces está bien (y es normal) si comienzas un proceso asincrónico (como un get o un readFile). Más tarde, cuando el resultado de ese proceso está disponible, se agrega un nuevo trabajo a la cola, el hilo de JavaScript lo recoge y usted usa res.send o similar para responder a la solicitud que ha estado esperando.

Así es como NodeJS gestiona el alto rendimiento a pesar de tener un solo subproceso: si usa E / S asíncrona en todo momento, su código real no tiene que ocupar el subproceso durante todo ese tiempo, porque no espera la E / S completar. Puede hacer más trabajo en otras cosas mientras la E / S está pendiente y luego responder cuando se completa la E / S.

4
Community 23 may. 2017 a las 11:46

Necesita cambiar su código de esta manera:

http.get(options, function(resp){
  resp.on('data', function(chunk){
    resp.send(chunk);
  });
}).on("error", function(e){
  console.log("Got error: " + e.message);
});
1
Pang 19 sep. 2018 a las 06:43