2017-01-30 5 views
1

Недавно я разрабатывал веб-приложение, и я понимаю, что я вообще не использую асинхронное свойство. Следовательно, я получаю много вложенных обратных вызовов.Node.js асинхронные случаи использования

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

db.query(<select list of permitted files_names>, function(err, filenames) { 
    async.each(file_names, function(name, next) { 
    //open each file to put into array 
    }); 
}) 

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

С вложенным обратным вызовом и асинхронной библиотекой этот код ведет себя как синхронный код.

names = db.querySync(//select list of permitted files_names); 
for(name in names) { 
    //open each file to put into array 
} 

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

Может кто-нибудь, пожалуйста, просветит меня, если есть какие-либо различия между этими двумя кодами с точки зрения производительности? Как использовать свойство non-blocking для повышения производительности в этом прецеденте?

+0

Поиска асинхронного/ждет в JavaScript –

+0

@ Aᴍɪʀ - почему бы асинхронная/Await иметь отношение? –

ответ

3

Если вы используете функции обратного вызова, которые вы используете по определению, используя асинхронные вызовы. Функция обратного вызова запускает только, когда операция завершена или с ошибкой. Вам не нужна модная библиотека, чтобы использовать их, это основа того, как работает Node event-loop driven subsystem.

Узел сильно рекомендует использовать вызовы «Синхронизация». Ядро Node включает в себя только удобство, они там как инструменты последнего запуска. Многие библиотеки даже не поддерживают их, поэтому вы абсолютно должны привыкнуть к написанию асинхронного кода. Например, в среде браузера вы просто не можете использовать блокирующие вызовы, не забирая время выполнения JavaScript и останавливая страницу.

Я предпочитаю использовать Promises Строка Bluebird реализует, чтобы код был упорядочен. Существуют и другие способы, такие как библиотека async, которые могут помочь справиться с другими сложными шаблонами вложенности.

Некоторые из льгот включают в себя такие вещи, как метод Promise.all, выполняет ряд обещаний до завершения, а затем запускает следующий шаг и Promise.map, который выполняет итерацию по списку, запуская асинхронный код для каждого элемента, а затем продвигаясь, когда список завершен.

Если вы дисциплинированы в организации своего кода, это не так уж плохо.Узел требует гораздо большего внимания к порядку операций, чем в традиционном синхронном по умолчанию языке, таком как Ruby, Python или Java, но вы можете привыкнуть к нему. Как только вы начнете работать с с помощью асинхронного кода, а не сражайтесь с ним, вы можете часто выполнять тонну работы, эффективно и с минимальной суетой, во многих случаях более эффективно, чем на других языках, где вы должны манипулировать потоками, а также блокировать и/или иметь дело с МПК.

+0

Привет, в отношении вышеприведенного примера, версия async vs sync такая же? Я не теряю параллелизм в синхронной версии? Я смущаюсь, согласуется ли параллелизм с одним запросом или параллелизмом между многими запросами. – Zanko

+1

Как только вы вызываете вызов Sync, все останавливается, пока эта операция не завершится. Для вызова базы данных, что может означать, что ваша программа ничего не делает ** в течение двух или трех секунд. Это совершенно неприемлемо для производственного кода. – tadman

+1

Синхронизирующие вызовы, которые я обычно делаю в программах, очень специфичны и тактичны, плюс происходят только во время фазы инициализации сценария, чтобы избежать проблем при регулярной работе.Например, тестирование, если файл существует до 'require'-load it, или итерации по каталогу для загрузки вещей в правильном порядке. После запуска программы выполняется только асинхронный режим. – tadman

2

Выгода проста: Используя асинхронный код, текущий поток (помните, Node.js является однопоточным) способен обрабатывать другие запросы, пока текущий запрос ожидает чего-то (например, запроса базы данных), чтобы вернуть ,

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


Чтобы сохранить код асинхронного чистый, смотреть в обещания (чтобы избежать глубоко вложенные обратных вызовов) и ES7 асинхронного/Await (чтобы избежать обратных вызовов на все и писать асинхронный код, который выглядит так же, как синхронный код).

+0

Привет, я надеюсь, что правильно понимаю, вы говорите, что если клиент A выполняет синхронно выше, а весь процесс занимает 10 секунд, а клиент B делает тот же запрос, клиент B должен ждать завершения клиента A? – Zanko

+1

'ES7 async/await' - еще не поддерживается в node.js, поэтому необходимо будет переписать –

+1

@ Zanko Предполагая, что вы используете только один экземпляр вашего веб-процесса, да, это правильно. Однако, используя асинхронный код, клиент B может получить ответ, в то время как клиент A все еще ждет, когда DB вернет данные. – Agop

2

Да, разница в двух кодах с точки зрения производительности.

В синхронном коде:

names = db.querySync(//select list of permitted files_names); 

вы звоните в базу данных здесь, чтобы дать список имен. Предположим, что это занимает 10 секунд. Итак, за это время nodeJS, поскольку это однопоточные gos в состояние блокировки. Через 10 секунд он выполняет остальную часть кода. Предположим, что это для цикла занимает 5 секунд, а некоторый код занимает 5 секунд.

for(name in names) { 
//open each file to put into array 
} 
//some code 

Для этого требуется общее время 20 секунд.

, тогда как в асинхронном коде:

db.query(<select list of permitted files_names>, function(err, filenames) { 

NodeJs запросит базу данных, чтобы дать список имен для обратного вызова. Предположим, что это занимает 10 секунд. И сразу он переходит на следующий шаг (некоторый код), но не в состояние блокировки. Предположим, что некоторый код занимает 5 секунд.

async.each(file_names, function(name, next) { 
//open each file to put into array 
}); 
}) 
//some code. 

Через 5 секунд он проверит, есть ли у него операции ввода-вывода. После возврата вызова. Он выполнит функцию (имя, далее) {..} за 5 секунд.

Таким образом, общее время составляет 15 секунд.

Таким образом, производительность улучшена.

Если асинхронный код должен быть чистым и аккуратным, тогда используйте затворы &.

Для Ex: Над асинхронный код может быть записан в виде

fun = function(err, filenames) { 
async.each(file_names, function(name, next) { 
//open each file to put into array 
} 
db.query(<select list of permitted files_names>, fun); 
Смежные вопросы