2013-06-14 3 views
7

Я изучаю node.js и заметил, что почти все обратные вызовы включены как анонимные обратные вызовы в функцию. Есть ли какая-то конкретная причина для этого?node.js - почему анонимные обратные вызовы

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

+1

Вопрос такого типа опроса лучше подходит для [чата] ;-) –

ответ

6

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

Рассмотрите довольно сложный плагин jQuery. Прежде чем генерировать и возвращать фактический объект, являющийся предметом плагина, может потребоваться создать десятки переменных, которые содержат временные данные состояния. Если это не было сделано в IIFE (сразу же вызванное функциональное выражение: анонимная функция, которая немедленно выполняется), эта переменная «просачивается» в глобальную область. Данные в JavaScript остаются в памяти, если есть какая-либо одна переменная или закрытие, все еще ссылающиеся на нее. Поскольку эти переменные «просочились» в глобальную область действия, они останутся в памяти до тех пор, пока эта вкладка/окно не будет закрыта. При определении внутри IIFE определенные переменные застревают в области локальной анонимной функции. Таким образом, когда функция завершила выполнение, переменные «ушли», и их данные больше не имеют ссылок. Сборщик мусора JS Engine замечает, что эти конкретные данные в памяти больше не упоминаются, и маркирует его для удаления, освобождая занятую память для других данных.

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

Это, по сути, описание того, как работают большинство динамических языков, и почему они более популярны, чем статические языки, такие как C, где вам нужно отслеживать каждое выделенное вами распределение памяти и удалять их, когда вы больше не нуждаетесь в них (упражнение само по себе, решение о том, как долго вам понадобятся данные, не всегда тривиально).

+2

Является ли это причудой конкретной реализации или общего поведения? Если последний, вы можете указать источник или конкретный пример? – icktoofay

+0

Это фундаментальная особенность/проблема сбора динамических языков с мусором. Это не просто javascript, а несколько других языков поддерживают анонимные функции (Scala, Haskell, лямбда-блоки Ruby и т. Д.). Я разберу этот ответ, чтобы включить пример универсального модуля jquery, поскольку его легче визуализировать, чем модуль nodejs. –

+0

Раньше я думал, что вы утверждаете, что такой код, как '(function() {function myCallback() {alert ('callbacked');} doSomething (myCallback);})();' был пропущен из-за использования имени но ваше редактирование, похоже, сосредоточено на наличии глобальных переменных. В случае, если определение функции является локальным для функции, использует ли именованные функции все еще негерметично? – icktoofay

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