2014-10-24 3 views
1

Мое знание предмета довольно низкое, поэтому, пожалуйста, несите меня.Какие функции должны быть асинхронными (помещать в обещания Node.js)?

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

Что на самом деле не был дан ответ после моих поисков является:

Если что-то вроде простой для цикла будет выполняться асинхронно? Это может быть что-то же просто, как:

function a() { 
    var a = 0; 
    for(i=0; i<10000000; i++) { 
     a++; 
    }; 
}; 

Так что-то вроде этого может занять несколько миллисекунд, следует ввести ее в обещание Node.js?

Правильно ли я предполагаю, что если я этого не сделаю, тогда да будет блокировка, хотя всего за несколько миллисекунд?

ответ

1

Поскольку что-то подобное может занять несколько миллисекунд, должно ли оно быть помещено в обещание Node.js?

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

+0

Думаю, проблема в том, что этот пример связан с ЦП, поэтому, если он не запущен в целом другом контексте V8, он все равно будет блокировать основной поток. Создание вещей async в первую очередь помогает для вещей, которые связаны с IO. – loganfsmyth

2

Я не уверен, правильно ли я вас понимаю, но я не думаю, что это будет работать так, как вы ожидаете. «Обтекание» этой функции внутри будущего сделает асинхронный вызов, но не самой функцией.

Предположим следующий сценарий:

f1(); 
a(); 
f2(); 
f3(); 
// (...) 

если a()f2() синхронно будет выполняться только после того, как a() отделок (т.е. ваш цикл). Теперь, если a() является асинхронным, это означает, что f2() будет выполнен сразу, поэтому он не блокирует выполнение.

Но поскольку NodeJS является однопоточным, и весь код выполняется в цикле, всякий раз, когда для цикла выполняется его выполнение, он запускается от начала до конца (от итерации от 0 до 9999999) без пауз, поэтому он блокирует другие операции в течение этого времени.

Так что, используя обещания, вы только задерживаетесь, когда этот код заблокирует ваше приложение.

Если эта функция занимает всего несколько миллисекунд, это может не иметь большого значения. Но если вам требуется несколько секунд или минут, вам нужно будет удостовериться, что задание время от времени возвращает управление NodeJS, используя nextTick или используя что-то вроде async.eachSeries.

This article объясняет, что это какая-то деталь.

0

Существует различие между «асинхронным запуском» и «написанием для асинхронности».

Как вы упомянули, NodeJS блокируется, когда он запускает цикл. Это означает, что больше ничего не будет запущено на CPU. Неважно, где эта функция вызывается, она будет использовать все циклы процессора, пока не закончится.

Если вы запускаете его асинхронно, используя библиотеку Promise или async, всякий раз, когда запускается for-loop, она будет работать вечно до тех пор, пока она не будет выполнена. В это время ничего больше не будет выполнено, он заблокирует все другие действия. Если вы напишете его для асинхронности, вы разделите цикл на более мелкие куски, которые будут выполняться асинхронно последовательно или параллельно, причем каждый кусок будет достаточно мал, чтобы не оказывать серьезного влияния на другие вещи, которые происходят.

Это несколько миллисекунд слишком много? Зависит от вашего приложения. Дело в том, что обработка будет должна произойти когда-нибудь, поэтому нет смысла слишком сильно ее разрушать. Просто имейте в виду, что цикл (и некоторые другие конструкции, такие как Array.forEach) блокируют ваши другие события от обработки, приложите все усилия, чтобы избежать проблем, и протестируйте приложение, насколько сможете.

0

Nodejs отличается от большинства других сред программирования тем, что все пользователи веб-приложения имеют один и тот же поток. Это означает, что если один пользователь запрашивает информацию из базы данных, вы не хотите, чтобы все остальные пользователи находились в очереди, чтобы запрос базы данных был завершен до обработки, скажем, запрос другого пользователя на загрузку страницы. Следовательно, это хорошая идея, насколько это возможно, освободить поток, чтобы Node мог обслуживать другие пользовательские запросы.

Теперь, что означает освобождение потока? По сути, двигатель V8 (подкрепляющий nodejs) выполняет команды поэтапно, как и большинство программистов. Однако возможно, что поток выполнения достигает точки, в которой он ожидает ввода из другого источника. Если функция записывается синхронно, выполнение просто ждет там до тех пор, пока вход не будет принят, а затем продолжит обработку остальной части программы. Однако, если функция написана неблокирующим (асинхронным) способом, поток освобождается для выполнения любых других доступных функций (например, новых запросов от других пользователей). Написание кода в неблокирующем режиме делает выполнение намного более эффективным в многопользовательской среде.

Теперь для вашей конкретной проблемы задан вопрос: если вы создадите функцию a(), асинхронно, вы освободите поток выполнения? Ответ - нет. Это связано с тем, что узел все еще выполняет цикл for, поэтому никакие другие функции не могут выполняться одновременно, и нет смысла приостанавливать выполнение узла, ожидая ввода другой системы. Итак, не делайте ваши асинхронные петли. Это просто добавляет сложности вашему коду и не дает никакого значения эффективности исполнения. Вместо этого попробуйте сделать так, чтобы циклы for выполнялись как можно эффективнее.

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