Как цикл ответа на запрос в узле js работает с внешним вводом-выводом

Полный новичок в node.js здесь. Я где-то видел этот пример "hello world"

// 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/");

Действительно простой код, в котором сервер отвечает на HTTP-запросы простым HTTP-ответом с простым текстом «Hello World».

Я также готов к библиотеке для выполнения HTTP-запросов из 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);
});

Здесь вы делаете HTTP-запрос с некоторыми параметрами, а затем что-то делаете с ответом в обратном вызове.

Что произойдет, если сделать такой запрос API, когда HTTP-запрос придет на сервер node.js? Поскольку поток должен быть однопоточным, как можно изменить состояние ответа, который node.js отправляет клиенту в обратном вызове запроса HTTP API? Не будет ли к тому времени ответ отправлен в цикл обработки событий? Как можно смоделировать синхронные запросы в этой системе, чтобы можно было использовать ответ запроса API для отправки ответа клиенту?


person Curious    schedule 04.03.2017    source источник


Ответы (2)


Поскольку поток должен быть однопоточным, как можно изменить состояние ответа, который node.js отправляет клиенту в обратном вызове запроса HTTP API?

Потому что ответ не отправляется синхронно с полученным запросом.

Не будет ли к тому времени ответ отправлен в цикл обработки событий?

Ответ не отправляется до тех пор, пока вы не вызовете res.send или аналогичный вызов, который не обязательно должен находиться в том же задании из очереди заданий, которое инициировало обратный вызов вашего запроса, и часто это не так.

Как можно смоделировать синхронные запросы в этой системе, чтобы можно было использовать ответ запроса API для отправки ответа клиенту?

В этом нет необходимости, и это убьет пропускную способность.

В любом заданном потоке (а NodeJS использует только один) JavaScript работает на основе очереди заданий: один поток JavaScript работает, выбирая задание из очереди, выполняя код для него все время. выполнить, а затем выбрать следующее задание из очереди (или бездействовать, пока оно не будет добавлено). Когда приходит событие или что-то подобное, если вы настроили обработчик для этого события, вызов вашего обработчика добавляется в очередь заданий. (На самом деле в очереди заданий есть как минимум два уровня; см. этот ответ, чтобы узнать больше об этом, если вам интересно. )

Это абсолютно нормально, если вы не отвечаете на «Мы получили HTTP-запрос» из кода задания, вызвавшего ваш обработчик. Это совершенно нормально. Работа и запрос полностью не связаны друг с другом. Так что это нормально (и нормально), если вы запускаете асинхронный процесс (например, get или readFile). Позже, когда результат этого процесса становится доступным, в очередь добавляется новое задание, поток JavaScript подхватывает его, и вы используете res.send или что-то подобное для ответа на ожидающий запрос.

Вот как NodeJS управляет высокой пропускной способностью, несмотря на наличие только одного потока: если вы повсеместно используете асинхронный ввод-вывод, ваш фактический код не должен занимать поток так долго, потому что он не ожидает ввода-вывода. завершить. Он может выполнять больше других задач, пока ожидается ввод-вывод, а затем реагировать на него, когда ввод-вывод завершится.

person T.J. Crowder    schedule 04.03.2017

Вам нужно изменить свой код следующим образом:

http.get(options, function(resp){
  resp.on('data', function(chunk){
    resp.send(chunk);
  });
}).on("error", function(e){
  console.log("Got error: " + e.message);
});
person Saddam    schedule 14.09.2018