Асинхронный JavaScript - обратные вызовы против отложенных/обещаний
Возможный дубликат:
В чем отличия между отложенными, обещаниями и будущими в Javascript?
В последнее время я прилагаю усилия для улучшения качества моих приложений JavaScript.
Один шаблон, который я принял, - использовать отдельный объект "контекст данных" для загрузки данных для моего приложения (ранее я делал это непосредственно в моделях просмотра).
Следующий пример возвращает данные, которые инициализируются клиентом:
var mockData = (function($, undefined) {
var fruit = [
"apple",
"orange",
"banana",
"pear"
];
var getFruit = function() {
return fruit;
};
return {
getFruit: getFruit
}
})(jQuery);
В большинстве случаев мы будем загружать данные с сервера, чтобы мы не могли вернуть немедленный ответ. Кажется, у меня есть два варианта того, как мы справляемся с этим в нашем API:
- Использование обратного вызова
- Возврат promise.
Раньше я всегда использовал подход обратного вызова:
var getFruit = function(onFruitReady) {
onFruitReady(fruit);
};
// ...
var FruitModel = function(dataContext, $) {
return {
render: function() {
dataContext.getFruit(function(fruit) {
// do something with fruit
});
}
};
};
Тем не менее, я вижу, как можно закончить в обратном ад, особенно при создании сложных приложений JavaScript.
Затем я наткнулся на шаблон дизайна Promises. Вместо того, чтобы требовать, чтобы вызывающий вызывал обратный вызов, я вместо этого возвращаю "обещание", которое можно наблюдать:
var getFruit = function() {
return $.Deferred().resolve(fruit).promise();
};
// ...
dataContext.getFruit().then(function(fruit) {
// do something with fruit
});
Я вижу очевидные преимущества использования этого шаблона, тем более, что я могу wait
на нескольких отложенных объектах, что может быть очень полезно при загрузке данных инициализации для одностраничного приложения.
Тем не менее, я очень хочу понять плюсы и минусы каждого шаблона, прежде чем я начну использовать либо в гневе. Меня также интересует, идет ли это направление, в которое входят другие библиотеки. Это похоже на jQuery.
Здесь ссылка к скрипту, которую я использую для тестирования.
Ответы
Ответ 1
Promises также полагаются на обратные вызовы за сценой, так что это действительно не один против другого.
Преимущество обратных вызовов заключается в том, что их легко реализовать с помощью обычного JavaScript (например, в вызовах ajax).
Promises требуется дополнительный уровень абстракции, что обычно означает, что вы будете полагаться на библиотеку (не проблема в вашем случае, поскольку вы уже используете jQuery). Они идеальны, когда вы параллельно используете несколько асинхронных вызовов.
Ответ 2
Из чтения jQuery docs, с которым связано @Pointy, похоже, что разница в том, что API отложенного кода позволяет указать более одного функция, которая будет вызываться, когда ваш запрос завершен:
Как и в jQuery 1.5, ошибка (сбой), успешность (завершена) и полная (всегда, с jQuery 1.6) обратные вызовы являются первыми в первом порядке управления очередями. Это означает, что вы можете назначить несколько обратных вызовов для каждого крючка. См. Методы отложенных объектов, которые внедрены внутри этих крючков обратного вызова $.ajax().
Смотрите также: deferred.then()