2016-10-10 3 views
0

Пусть у меня есть следующий код в приложение Node.js:Понимание Что такое синхронизация и Что Асинхронный в Node.js/JavaScript

function bar(){ 
    //do_stuff 
    return value; 
} 

app.get('/',function(req,res){ 
    var result = bar(); 
    res.send(result); 
}); 
  1. Предположим, что в функции бар// do_stuff - это цикл while до 10 миллионов. Гарантируется, что функция завершится, вернет ее значение, которое будет присвоено результат, и только тогда res.send (результат) будет выполнен?

  2. Что делать, если в функции bar // do_stuff включал запросы к базе данных (и возвращаемое значение зависело от этих запросов). В этом случае я мог быть уверен, что res.send (результат) будет выполнен с правильным значением, возвращенным после завершения функции bar?

+0

Итак, ваше первое предположение верно. Если вы выполните функцию и вызовите эту функцию, весь ваш код будет завершен до res.send. Теперь, если в этих функциях вы выполняете любые запросы к базе данных, они не будут ждать завершения этих запросов до перехода. – Ohjay44

+0

Что еще, кроме запросов к базе данных, время ожидания не будет ждать? Где я могу найти дополнительную информацию об этом поведении? –

+0

Все, что связано с тем, что вы покидаете текущее окружение. Так, например, если у вас несколько микросервисов, и вы вызываете одну услугу с другой, узел не будет ждать обратного вызова, прежде чем он сделает res.send. Поэтому, если ваш код покидает ваше текущее пространство узла, он не будет ждать. Однако есть способы заставить его ждать. – Ohjay44

ответ

2

Async - это в основном все, что мешает окружающей среде вне вашего JavaScript. И не потому, что это необходимо, а потому, что это прагматичный. Async хорош для трудоемких задач, поскольку он не блокирует основной поток JS.

В случае цикла while, как правило, нет необходимости делать его асинхронным, хотя вы можете сделать его асинхронным, если хотите (например, вы знаете, что для вычисления потребуется много времени, и вы не хотите блокировать свои основной поток). Если запрос HTTP или запрос базы данных не будет асинхронным, механизм JS будет просто останавливаться и ничего не делать до тех пор, пока результат не достигнет, что не является большой проблемой в Node.js, но в случае веб-страниц это заморозит пользовательский интерфейс, которые, несомненно, будут раздражать некоторых пользователей.

Есть несколько способов решения задач асинхронного

  • обратных вызовов - функция, которая обрабатывает задачу асинхронной, принимает в качестве параметра другой функции, т.е. callback, который будет называться как только задача (обычно он принимает обратный вызов для успеха и обратный вызов для случая ошибки).
  • события - функция, которая обрабатывает асинхронную задачу, сразу возвращает объект, который является event emitter. Вы присоединяете обратные вызовы к событиям, которые этот эмиттер генерирует, и эти обратные вызовы затем вызывается эмиттером по мере возникновения событий. Эти обратные вызовы отмечены как прослушиватели событий.
  • обещания - функция, которая обрабатывает задачу асинхронной, немедленно возвращает объект, который представляет собой promise некоторых будущий результат. Это обещание имеет такие методы, как then(), fail(), always(), через которые вы можете зарегистрировать свои обратные вызовы. Это очень похоже на излучатель событий, обещания предлагают лучший контроль потока данных, но при его создании нельзя прервать.
  • ES next - В будущих версиях JavaScript приводятся генераторы ES6 или асинхронные функции ES7.

Вы можете отличить async от факта, что он не возвращает результат немедленно, но обычно позволяет регистрировать обратные вызовы для последующего вызова либо через параметры/аргументы, либо с помощью методов возвращаемого объекта.

Примечание: в случае ES6 и ES7 для асинхронного процесса не требуется обратных вызовов, но я больше не буду усложнять эту тему этой новой технологией.

for loop не позволяет регистрировать обратные вызовы, он просто занимает JS-движок и делает всю итерацию настолько быстрой, насколько это возможно.

+0

«вы знаете, что для вычисления потребуется много времени» --- если асинхронные задачи не должны быть привязаны к IO. Это, вероятно, плохо сформулировано, но «вычисление» звучит как нечто, связанное с ЦП. – zerkms

+0

@zerkms, в браузере, у нас есть ['WebWorker'] (https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers), который позволяет запускать некоторый вычислительный интенсивный код в отдельном потоке или мы можем создать обещание и разрешить его в 'setTimeout (callback, 0)', который создаст что-то вроде второго потока и не будет блокировать основной поток. Возможно, он не является асинхронным по своей природе, но с ним обращаются одинаково. – Vaclav

+0

Работники веб-сайтов являются частью веб-ави, а не стандартом ES. Непонятное упоминание о них актуально, когда речь идет о (а) синхронном характере языка. – zerkms

Смежные вопросы