Обратные вызовы

Я создаю небольшой скрипт, чтобы лучше понять обратный вызов.

Из приведенного ниже сценария поведение, которое я ожидал, было следующим: «http.get запускается и занимает в среднем 200 мс. Приращение цикла for «i» занимает в среднем 2500 мс. Через 200 мс процесс должен завершиться, а сценарий должен быть остановлен. чтобы работать.Почему он печатает все я?Если я понимаю это лучше, я думаю, что понимаю обратного вызова.

var http = require("http");
var starttime = new Date();

//Function with Callback
for (var j =0; j<10; j++){
    http.get({host : 'nba.com'}, function(res){
        console.log("Time Taken = ", new Date() - starttime, 'ms');

        process.exit();
    }).on('error', function(er){
        console.log('Got Error :', er.message);
    })
}

//Loop that exceeds callback trigger time
for(var i=1; i<10000; i++){
    console.log(i);
}

console.log("Time Taken = ", new Date() - starttime, 'ms');

person PatrickJames    schedule 16.08.2016    source источник
comment
Цикл for является синхронным, а код в нем — асинхронным. Он проходит через цикл for, запуская вызов get async get. Цикл for завершается до того, как сработают обратные вызовы on. В Интернете есть множество документов и примеров, иллюстрирующих, как работает асинхронность.   -  person bryanmac    schedule 16.08.2016
comment
Спасибо, Брайанмак. Я проверю их. Теперь ясно, как облако.   -  person PatrickJames    schedule 16.08.2016


Ответы (1)


Javascript в node.js является однопоточным, а ввод-вывод управляется событиями с использованием очереди событий. Таким образом, ваши асинхронные обратные вызовы, которые сигнализируют о завершении HTTP-запросов, не могут выполняться до тех пор, пока ваш исходный поток Javascript не завершится и не вернет управление обратно в систему, где она может затем извлечь следующее событие из очереди событий для обслуживания завершения http-запроса.

Таким образом, ваш цикл for будет завершен до того, как будут обработаны какие-либо ответы http.

Вот пошаговый процесс:

  1. Ваш первый цикл for выполняется и отправляет 10 HTTP-запросов.
  2. Эти http-запросы выполняются в фоновом режиме с использованием асинхронной сети. Когда один из них завершится и получит ответ, модуль http поместит событие в очередь событий Javascript, и задача интерпретатора JS будет извлекать это событие из очереди событий, когда оно завершит другие свои действия.
  3. Ваш второй цикл for выполняется до завершения, и все значения i выводятся на консоль.
  4. Ваш сценарий завершается.
  5. Затем интерпретатор JS проверяет очередь событий на наличие ожидающих событий. В этом случае будут некоторые события ответа http. Интерпретатор JS извлекает самое старое событие из очереди событий и вызывает связанный с ним обратный вызов.
  6. Когда этот обратный вызов завершается, следующее событие извлекается из очереди событий, и процесс продолжается до тех пор, пока очередь событий не станет пустой.
  7. Если какой-либо из ваших обратных вызовов вызывает process.exit(), это замыкает оставшиеся обратные вызовы и немедленно завершает процесс.

Хотя этот другой ответ был написан для браузера, однопоточная концепция, управляемая событиями, такая же, как и в node.js, поэтому этот другой ответ может объяснить вам еще некоторые вещи: Как JavaScript обрабатывает ответы AJAX в фоновом режиме?

person jfriend00    schedule 16.08.2016
comment
Спасибо Jfiend00. Это ясно объясняет это. То, что я забыл для сети или ввода-вывода, является асинхронным, в то время как ЦП синхронизируется из-за однопоточного. Цикл for связан с ЦП и не имеет ввода-вывода. Имеет смысл. - person PatrickJames; 16.08.2016