Я понимаю идею обратного вызова, когда я передаю функцию в другую функцию, и эта функция затем использует предоставленную функцию по желанию.
Я изо всех сил пытаюсь понять отложенные обратные вызовы, даже после поиска в Google.
Может ли кто-нибудь дать простое объяснение, пожалуйста? Я программирую на Ruby, но также немного знаю C / C ++, но больше всего я был опытным программистом на ассемблере. Итак, мне интересно, это немного похоже на стек обратных вызовов, которые получают pop'd? Я надеюсь изучить jquery или node.js, и эти отложенные обратные вызовы кажутся неотъемлемой частью обоих. Я понимаю основные принципы работы с потоками (хотя объект-мьютекс заставляет мою голову болеть;)
Deferred
объекты jQuery ? Это что-то конкретное для Node.js?Ответы:
По желанию, вот комментарии, представленные в качестве ответа:
Я не уверен, что вы полностью осознаете тот факт, что функции в JS являются первоклассными объектами и поэтому могут храниться до тех пор, пока они не понадобятся, по истечении времени их создания.
Например, скажем, вы хотите записать в файл, а затем распечатать сообщение журнала; поэтому вы вызываете функцию «write ()» (или как угодно) и передаете ей функцию, которая выводит сообщение журнала (это функция отложенного обратного вызова). «write ()» внутренне хранит ссылку на данную функцию, начинает запись в файл и устанавливает свой собственный обратный вызов, чтобы знать, когда запись завершена. Затем он возвращается до завершения записи; когда это так, внутренний обратный вызов как-то вызывается (это работа базового фреймворка - в случае с node.js это делается с помощью цикла обработки событий), который затем вызывает ваш обратный вызов, который печатает сообщение журнала.
«Отложенная» часть просто означает, что ваша функция обратного вызова не вызывается сразу; Вызов его откладывается до соответствующего времени. В случае асинхронных функций, таких как многие из таковых в node.js, данный обратный вызов обычно вызывается, когда операция завершается (или возникает ошибка).
Большая часть содержимого является async в node.js, но в браузере с, например, jQuery, большая часть содержимого фактически синхронна (за исключением, очевидно, для запросов AJAX). Так как первоклассные функции очень удобны в JavaScript (особенно из-за большой поддержки замыканий), обратные вызовы также используются повсюду в браузере, но они не «откладываются» для синхронных операций (кроме тех случаев, когда они не вызываются немедленно вы, но позже с помощью функции, которую вы вызываете).
Тот факт, что базовая система управляется событиями, является ортогональным к использованию отложенных обратных вызовов; Вы можете представить себе (очень медленную) версию node.js, которая запускает поток для каждой операции, а затем вызывает заданный обратный вызов, когда поток завершает свою работу, вообще не используя события. Конечно, это ужасная модель, но она иллюстрирует мою точку зрения :-)
источник
Способ отложенного обратного вызова работает каждый раз, когда вы добавляете к нему обратный вызов, этот обратный вызов помещается в массив. Затем, когда метод
.resolve()
or.resolveWith()
вызывается для отложенного объекта, все.done()
обратные вызовы в массиве выполняются по порядку.Теперь мы можем посмотреть, что такое отложенный объект. Возьмите фрагмент ниже в качестве примера.
Теперь у нас есть отложенный объект и объект обещания отложенного объекта. Отложенный объект имеет все те же методы, что и объект обещает, однако объект обещания имеет только методы
.done()
,.fail()
и.always()
которые используются для добавления обратных вызовов к отсроченному объекту для каждого соответствующегоevent
. У отложенного объекта, с другой стороны, есть несколько других методов, наиболее важно.resolve()
и.reject()
. Когда эти методы вызываются для отложенного объекта, все обратные вызовы вызываются..resolve()
запускает.done()
и.always()
обратные вызовы, а.reject()
метод вызывает.fail()
и.always()
обратные вызовы.Обычно отложенный объект хранится скрытым в закрытой области видимости, а объект обещания возвращается из функции, чтобы на него могли быть помещены обратные вызовы. Отложенный объект будет разрешен позже, например, после завершения запроса ajax или после загрузки изображения, после setTimeout и т. Д. Также важно понимать, что отложенный объект может быть разрешен только один раз. Если это уже решено, его обратные вызовы будут вызваны немедленно.
Вот еще один пример, который я использую:
Для получения дополнительной информации о
$.Deferred()
методе jQuery и отложенных объектах, посетите http://api.jquery.com/category/deferred-object/источник
Я не уверен, но я полагаю, что отложенный обратный вызов относится к асинхронному обратному вызову, так что вам повезет больше в этом.
Лучшее объяснение, которое я нашел, было на http://www.nodebeginner.org
В этом примере, вероятно, ExferenceFunction является неблокирующей (или асинхронной функцией). Это означает, что он не выполняется сразу, а помещается в так называемый цикл обработки событий. Поток node.js продолжит выполнение, но в какой-то момент он решит выполнить что-то из цикла событий. Когда он достигает вероятно, дорогой функции, он вызывает его, а когда, вероятно, дорогая функция завершает выполнение, он вызывает (отложенный) обратный вызов, переданный в качестве параметра для него.
В качестве примера, вероятно, дорогой функции вы можете взять fs.readFile
источник
.resolve()
или.reject()
исходный отложенный объект, вызывается список обратных вызовов.JavaScript является однопоточным, поэтому вы не можете думать с точки зрения потоков, чтобы понять это. Вот пример как обычных, так и асинхронных обратных вызовов с использованием jQuery:
источник
Отложенные обратные вызовы (иначе как Promices ) позволяют вам писать последовательный асинхронный код без боли и спагетти обратного вызова:
«когда» позволяет вам ожидать параллельного возврата функций и
then
может быть последовательно соединено.одно замечание: jQuery deferreds ! = Promices / A , их синтаксис немного другой.
На эту тему есть хорошие статьи: одна в IEBlog, другая в каком-то случайном блоге , книга и популярный вопрос stackoverflow
источник