В чем разница между синхронным и асинхронным программированием (в node.js)

Я читал nodebeginner И я наткнулся на следующие две части кода.

Первый:

    var result = database.query("SELECT * FROM hugetable");
    console.log("Hello World");

Второй:

    database.query("SELECT * FROM hugetable", function(rows) {
       var result = rows;
    });
    console.log("Hello World");

Я получаю то, что они должны делать, они запрашивают базу данных для получения ответа на запрос. А затем console.log('Hello world').

Первый - предположительно синхронный код. А второй - асинхронный код.

Разница между двумя частями очень расплывчата для меня. Каким будет выход?

Поиск по асинхронному программированию тоже не помог мне.

Ответ 1

Разница в том, что в первом примере программа будет блокироваться в первой строке. Следующая строка (console.log) должна будет подождать.

В втором примере console.log будет выполняться WHILE, когда запрос обрабатывается. То есть запрос будет обрабатываться в фоновом режиме, в то время как ваша программа выполняет другие функции, и как только данные запроса будут готовы, вы сделаете все, что хотите, с ней.

Итак, в двух словах: первый пример будет заблокирован, а второй - нет.

Вывод следующих двух примеров:

// Example 1 - Synchronous (blocks)
var result = database.query("SELECT * FROM hugetable");
console.log("Query finished");
console.log("Next line");


// Example 2 - Asynchronous (doesn't block) 
database.query("SELECT * FROM hugetable", function(result) {
    console.log("Query finished");
});
console.log("Next line");

Будет:

  • Query finished
    Next line
  • Next line
    Query finished

Примечание
В то время как Node сам однопоточный, есть несколько задач, которые могут выполняться параллельно. Например, операции файловой системы происходят в другом процессе.

Вот почему Node может выполнять асинхронные операции: один поток выполняет операции файловой системы, а основной поток Node продолжает выполнять ваш код javascript. На сервере, подобном событиям, например Node, поток файловой системы уведомляет основной поток Node определенных событий, таких как завершение, сбой или прогресс, а также любые данные, связанные с этим событием (например, результат работы базы данных запрос или сообщение об ошибке), а основной поток Node определяет, что делать с этими данными.

Подробнее об этом можно прочитать здесь: Как работает однопоточная неблокирующая IO-модель в Node.js

Ответ 2

Разница между этими двумя подходами такова:

Синхронный путь: Он ждет завершения каждой операции, после чего только она выполняет следующую операцию. По вашему запросу: Команда console.log() не будет выполняться до тех пор, пока не завершится выполнение запроса, чтобы получить весь результат из базы данных.

Асинхронный путь: Он никогда не ждет завершения каждой операции, а выполняет все операции только в первом GO. Результат каждой операции будет обработан после получения результата. По вашему запросу: Команда console.log() будет запущена вскоре после метода Database.Query(). Пока запрос базы данных выполняется в фоновом режиме и загружает результат после завершения извлечения данных.

Использовать случаи

  • Если ваши операции не очень сильно поднимаются, например, запрашивая огромные данные из БД, тогда используйте синхронный способ иначе асинхронный.

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

Ответ 3

Это станет немного более ясным, если вы добавите строку в оба примера:

var result = database.query("SELECT * FROM hugetable");
console.log(result.length);
console.log("Hello World");

Второй:

database.query("SELECT * FROM hugetable", function(rows) {
   var result = rows;
   console.log(result.length);
});
console.log("Hello World");

Попробуйте запустить их, и вы заметите, что первый (синхронный) пример, result.length будет распечатан до линии "Hello World" . Во втором (асинхронном) примере длина результата будет (скорее всего) напечатана ПОСЛЕ строки "Hello World" .

Это потому, что во втором примере database.query выполняется асинхронно в фоновом режиме, а script продолжается сразу с помощью "Hello World" . console.log(result.length) выполняется только после завершения запроса базы данных.

Ответ 4

Во-первых, я понимаю, что опаздываю, отвечая на этот вопрос.

Прежде чем обсуждать синхронные и асинхронные, давайте вкратце рассмотрим, как работают программы.

В случае синхронного каждый оператор завершается до запуска следующего оператора. В этом случае программа вычисляется точно в порядке операторов.

Вот как работает асинхронный в JavaScript. В движке JavaScript есть две части: одна часть, которая смотрит на операции с кодом и enqueues, а другая - на обработку очереди. Обработка очереди происходит в одном потоке, поэтому за один раз может произойти только одна операция.

Когда отображается асинхронная операция (например, второй запрос базы данных), код анализируется и операция помещается в очередь, но в этом случае обратный вызов регистрируется для запуска, когда эта операция завершается. В очереди может быть уже много операций. Операция в передней части очереди обрабатывается и удаляется из очереди. После обработки операции для запроса базы данных запрос отправляется в базу данных и по завершении обратного вызова будет выполнен по завершении. В это время процессор очереди, "обработанный" операцией, перемещается при следующей операции - в этом случае

    console.log("Hello World"); 

Запрос базы данных все еще обрабатывается, но операция console.log находится в передней части очереди и обрабатывается. Это синхронная операция запускается сразу же, что сразу же появляется на выходе "Hello World". Спустя некоторое время операция базы данных завершается, и только тогда обратный вызов, зарегистрированный в запросе, вызывается и обрабатывается, устанавливая значение результата переменной в строки.

Возможно, что одна асинхронная операция приведет к другой асинхронной операции, эта вторая операция будет помещена в очередь, а когда дело доходит до передней части очереди, она будет обработана. Вызов обратного вызова, зарегистрированного в асинхронном режиме, показывает, как время выполнения JavaScript возвращает результат операции, когда это делается.

Простым способом знать, какая операция JavaScript является асинхронной, - это отметить, что для нее требуется обратный вызов - обратный вызов - это код, который будет выполняться при завершении первой операции. В двух примерах в вопросе мы видим, что только второй случай имеет обратный вызов, поэтому это асинхронная операция двух. Это не всегда происходит из-за разных стилей обработки результата асинхронной операции.

Чтобы узнать больше, прочитайте о promises. Promises - это еще один способ, с помощью которого можно выполнить результат асинхронной операции. Самое приятное в Promises заключается в том, что стиль кодирования больше похож на синхронный код.

Многие библиотеки, такие как node 'fs', предоставляют как синхронные, так и асинхронные стили для некоторых операций. В случаях, когда операция не занимает много времени и не используется много - как в случае чтения файла конфигурации - операция синхронного стиля приведет к тому, что код легче читать.

Ответ 5

В синхронном случае команда console.log не выполняется до завершения выполнения SQL-запроса.

В асинхронном случае команда console.log будет выполняться непосредственно. Затем результат запроса будет сохранен функцией "обратного вызова" через некоторое время.

Ответ 6

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

Ответ 7

Функция делает вторую асинхронной.

Первый заставляет программу ждать завершения каждой строки до того, как она будет продолжена. Второй способ позволяет каждой строке работать вместе (и независимо) сразу.

Языки и фреймворки (js, node.js), которые позволяют асинхронно или concurrency, отлично подходят для вещей, требующих передачи в реальном времени (например, чат, приложения для акций).

Ответ 8

Синхронизация

Языки программирования, такие как C, С#, Java, - это синхронизация, то, что вы когда-либо пишете, будет выполняться в порядке вашего письма.

-GET DATA FROM SQL.
//Suppose fetching data take 500 msec

-PERFORM SOME OTHER FUNCTION.
//Performing some function other will take 100 msec, but execution of other 
//task start only when fetching of sql data done (i.e some other function 
//can execute only after first in process job finishes).

-TOTAL TIME OF EXECUTION IS ALWAYS GREATER THAN (500 + 100 + processing time) 
msec

асинхронный

NodeJs имеет асинхронную функцию, которая не блокирует природу, предположим, что в любой задаче ввода-вывода, которая занимает время (выборка, запись, чтение), nodejs не будет оставаться в режиме ожидания и ждать завершения задачи, я начну выполнять следующие задачи в очереди, и всякий раз, когда эта задача будет выполнена, он будет уведомлять об использовании обратного вызова. Следующий пример поможет:

//Nodejs uses callback pattern to describe functions.
//Please read callback pattern to understand this example

//Suppose following function (I/O involved) took 500 msec
function timeConsumingFunction(params, callback){
  //GET DATA FROM SQL
  getDataFromSql(params, function(error, results){
    if(error){
      callback(error);
    }
    else{
      callback(null, results);
    }
  })
}

//Suppose following function is non-blocking and took 100 msec
function someOtherTask(){
  //some other task
  console.log('Some Task 1');
  console.log('Some Task 2');
}

console.log('Execution Start');

//Start With this function
timeConsumingFunction(params, function(error, results){
    if(error){
      console.log('Error')
    }
    else{
      console.log('Successfull'); 
    }
  })

//As (suppose) timeConsumingFunction took 500 msec, 
//As NodeJs is non-blocking, rather than remain idle for 500 msec, it will start 
//execute following function immediately
someOtherTask();

В Short, Output:

Execution Start
//Roughly after 105 msec (5 msec it'll take in processing)
Some Task 1
Some Task 2
//Roughly After 510 msec
Error/Successful //depends on success and failure of DB function execution

Разница очевидна, когда синхронизация определенно занимает более 600 (500 + 100 + время обработки) мсек, асинхронный режим экономит время.