Как объяснить обратные вызовы на простом английском языке?
Говоря простым языком, функция обратного вызова похожа на рабочий , который "перезванивает" своему менеджеру , когда он выполнил задачу .
Чем они отличаются от вызова одной функции из другой функции
взять некоторый контекст из вызывающей функции?
Это правда, что вы вызываете функцию из другой функции, но ключ в том, что обратный вызов обрабатывается как объект, так что вы можете изменить какую функцию вызывать в зависимости от состояния системы (например, шаблон проектирования стратегии) ).
Как объяснить их силу начинающему программисту?
Мощь обратных вызовов легко увидеть на веб-сайтах в стиле AJAX, которым необходимо получать данные с сервера. Загрузка новых данных может занять некоторое время. Без обратных вызовов весь пользовательский интерфейс "зависнет" при загрузке новых данных, или вам нужно будет обновить всю страницу, а не только ее часть. С помощью функции обратного вызова вы можете вставить «загружаемое» изображение и заменить его новыми данными после загрузки.
Некоторый код без обратного вызова:
function grabAndFreeze() {
showNowLoading(true);
var jsondata = getData('http://yourserver.com/data/messages.json');
/* User Interface 'freezes' while getting data */
processData(jsondata);
showNowLoading(false);
do_other_stuff(); // not called until data fully downloaded
}
function processData(jsondata) { // do something with the data
var count = jsondata.results ? jsondata.results.length : 0;
$('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
$('#results_messages').html(jsondata.results || '(no new messages)');
}
с обратным вызовом:
Вот пример с обратным вызовом, использующим jQuery getJSON :
function processDataCB(jsondata) { // callback: update UI with results
showNowLoading(false);
var count = jsondata.results ? jsondata.results.length : 0;
$('#counter_messages').text(['Fetched', count, 'new items'].join(' '));
$('#results_messages').html(jsondata.results || '(no new messages)');
}
function grabAndGo() { // and don't freeze
showNowLoading(true);
$('#results_messages').html(now_loading_image);
$.getJSON("http://yourserver.com/data/messages.json", processDataCB);
/* Call processDataCB when data is downloaded, no frozen User Interface! */
do_other_stuff(); // called immediately
}
с закрытием:
Часто для обратного вызова требуется доступ к state
из вызывающей функции с использованием closure
, что похоже на Worker , которому необходимо получить информацию от Manager , прежде чем он сможет завершить его Задача . Чтобы создать closure
, вы можете встроить функцию, чтобы она видела данные в контексте вызова:
/* Grab messages, chat users, etc by changing dtable. Run callback cb when done.*/
function grab(dtable, cb) {
if (null == dtable) { dtable = "messages"; }
var uiElem = "_" + dtable;
showNowLoading(true, dtable);
$('#results' + uiElem).html(now_loading_image);
$.getJSON("http://yourserver.com/user/"+dtable+".json", cb || function (jsondata) {
// Using a closure: can "see" dtable argument and uiElem variables above.
var count = jsondata.results ? jsondata.results.length : 0,
counterMsg = ['Fetched', count, 'new', dtable].join(' '),
// no new chatters/messages/etc
defaultResultsMsg = ['(no new ', dtable, ')'].join('');
showNowLoading(false, dtable);
$('#counter' + uiElem).text(counterMsg);
$('#results'+ uiElem).html(jsondata.results || defaultResultsMsg);
});
/* User Interface calls cb when data is downloaded */
do_other_stuff(); // called immediately
}
Использование:
// update results_chatters when chatters.json data is downloaded:
grab("chatters");
// update results_messages when messages.json data is downloaded
grab("messages");
// call myCallback(jsondata) when "history.json" data is loaded:
grab("history", myCallback);
Закрытие
Наконец, вот определение closure
из Дуглас Крокфорд :
Функции могут быть определены внутри других функций. Внутренняя функция имеет доступ к переменным и параметрам внешней функции. Если ссылка на внутреннюю функцию сохраняется (например, в качестве функции обратного вызова), переменные внешней функции также сохраняются.
Смотри также: