Promise в AngularJS на примере Restangular
Чаще всего Promise объекты используются при работе с HTTP запросами. При отправке запроса мы получаем Promise объект, с помощью которого задаем callback функции для обработки результата запроса и ошибок, которые могут возникнуть. Подробнее об этом написано в спецификации "Promises Specification from Kris Kowal" - https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md.
Сигнатура Promise объекта
promise.then(successCallback, errorCallback, loadingCallback) .catch(function(e) { ... })
.finally(function() { ... });
Пример использования Promise объекта
var promise = Rest.one('users', 2014).get().then(function(users) {
// Обрабатываем успешный запрос
}, function(errorResponse) {
// Обрабатываем ошибку при выполнении запроса
// Это тот же обработчик, что и then().catch(errorCallback)
},
function(progres) { // progres || percentComplete || notify
// Походу, это либо метод для получения информации о прогрессе выполнения запроса (как-то связан с Node.js).
// Либо это метод для работы с Long-Pooling соединением..
})
.catch(function(e) {
// Ловим ошибки..
// returned null, or other server error, or error in previous then handler
})
.finally(function() { // @see http://bit.ly/1rSqrCz
// Выполняем действие по завершению запроса, независимо от статуса выполнения (resolved или rejected)
// Например: скрыть лоадер (spinner), активировать или показать предварительно скрытую кнопку..
});
Как видите, с Promise объектами все довольно просто - главное попрактиковаться с ними.
Примечание
Поскольку finally это зарезервированное слово в JavaScript - к нему нельзя обращаться через нотацию object.property (согласно ES3). Для совместимости с IE8 и Android 2.x нужно задавать обработчик для этого метода так:
promise['finally'](callback)
Пример установки таймаута запроса через промис:
var canceler = $q.defer();
Rest.all('controller').withHttpConfig({timeout: canceler.promise}).one('action').get().finally(function() {
console.log('finally');
});
// Сообщить о тайм-ауте через 10 сек
setTimeout(function() {
canceler.resolve();
}, 10000);
#angularjs, #promise