При создании сервисного уровня в приложении Angular я заметил много повторений кода для создания обещаний, поэтому попытался создать общий сервис getPromise, поскольку 90% обещаний имеют одинаковую структуру.
Хотя при возврате обещания из службы функция не выполняется как обычно, хотя возвращаемый объект тот же.
Кто-нибудь пробовал это делать? Например.
angular.module('fooApp')
.service('promise', function promise($q, $http) {
return {
getPromise: function (url, data) {
var deferred = $q.defer();
$http.post(url, data)
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
deferred.reject(error);
});
return deferred.promise;
}
};
})
.service('foo', function foo(config, promise) {
return {
getFoo: function (userId) {
var deferred = $q.defer();
var url = config.svcUser + 'GetFoo';
var data {
userId: userId
};
$http.post(url, data)
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
deferred.reject(error);
});
return deferred.promise;
},
getFoo2: function (userId) {
var url = config.svcUser + 'GetFoo';
var data {
userId: userId
};
return promise.getPromise(url, data);
}
}
})
.controller('AgenciesCtrl', function ($scope, agency) {
agency.getFoo().then(function (agencies) {
// does fire
});
agency.getFoo2().then(function (foo) {
// does not fire
});
$scope.loadAgency = function (agencyId) {
agency.getFullAgencyProfile(agencyId).then(function (agency) {
$scope.agency = agency;
});
}
});
В этом небольшом примере проблема кажется довольно легкой, но я планирую реализовать более 30 сервисов, чтобы, если возможно, значительно сократить повторение кода.
2 ответа
Ты прав! Ваш код повторяется - это называется < strong>отложенный антишаблон.
Обещает абстрактные значения, которые являются временными, то есть: они еще не доступны. Точно так же, как ваш код обычно связывает (одна строка за другой), так и промисы с then
.
Обещания Angular, поскольку обещания A+ предлагают довольно современную реализацию, и все, что Angular делает асинхронно, логически представляет собой однократную операцию уже возвращает обещание. Сюда входит все, что делает $http, а также $timeout, $resource и так далее.
Ваш код мог бы быть намного проще:
angular.module('fooApp')
.service('foo', function foo(config, promise) {
return {
getFoo: function (userId) {
var url = config.svcUser + 'GetFoo';
var data { userId: userId };
return $http.post(url, data).then(function(resp){
// any validations you need on the response go here
return response.data;
});
}
}
}).controller('AgenciesCtrl', function ($scope, foo) {
foo.getFoo().then(function (agencies) {
// does fire, and schedules a digest because it's an Angular promise
$scope.someVar = agencies; // safe to do here, since a digest will happen
});
});
//any validation
. если вы считаете, что мой ответ решил вашу проблему, подумайте о том, чтобы принять его (хотя не чувствуйте давления).
Вот что я обычно делаю
В вызове метода службы:
return $http.post(url,data,{})
.success(function(response){
return response.data;
})
.error(function(response){
// return error / status code
}); // end $http.post
Затем в контроллере:
var data = someSrvc.methodCall();
// you could also follow this up with
$q.when(data).then(...);
Или же
В сервисе:
return $http.post(url,data,{});
Затем в контроллере (или где бы то ни было):
someSrvc.methodCall().then(function(response){
// some success code
},function(response){
// some error code
}); // end methodCall
Пример $q.when превратить что-то в обещание:
$q.when((someVal <= 0) && (someOtherVal > 0))
.then(function(){
// do something when condition is true
});
Я иногда делаю это, когда я повторно использую массив, но мне нужно, чтобы он был очищен. Самый быстрый способ усечь массив - это удалить все его значения, НЕ устанавливая его длину непосредственно в ноль или устанавливая его в пустой массив. Я знаю, что это кажется нелогичным, но посмотрите сами. Так что в любом случае что-то вроде этого:
while(myArray1.length > 0)
myArray1.pop();
while(myArray2.length > 0)
myArray2.pop();
$q.when((myArray1.length <= 0) && (myArray2.length <= 0)).then(function(){
// do something
});
success
не связывает (возвращает одно и то же обещание) - ваше использование $q.when
бессмысленно, рискованно и откладывает без причины (нет смысла делать асинхронность, когда это не так). требуется, это просто медленно и запутанно), вы также делаете $q.when
без веской причины для вещей, которые уже являются обещаниями.
Похожие вопросы
Связанные вопросы
Новые вопросы
angularjs
Используйте для вопросов об AngularJS (1.x), JavaScript-фреймворке с открытым исходным кодом. НЕ используйте этот тег для Angular 2 или более поздних версий; вместо этого используйте тег [angular].
$http.post
возвращает обещание, не нужно оборачивать его$q
. Я не уверен, почему люди этого не понимают. Также хорошая идея с сервисом обернуть код X промисом, но вы уже можете сделать это с помощью$q.when(...)
= Оборачивает объект, который может быть значением или (сторонним) тогда-способным промисом, в $ д обещание