我想问一下是否有可能返回递归工厂方法。我将展示一些代码,以便您更了解我。 我们有工厂:
angular.module('module')
.factory('synchronizationStatus', ['$http', 'apiBase', '$timeout', function ($http, apiBase, $timeout) {
var service_url = apiBase.url;
function syncCompleted ( correlationId ) {
checkSync (correlationId)
.then(function(response){
$timeout(function() {
// if I get response.data true, i want to proceed to controller
if(response.data){
return "now I want to return result to controller"
}
else {
// check again
checkSync(correlationId)
}
}, 500);
})
}
function checkSync( correlationId ){
return $http.get(service_url + query);
}
return {
syncCompleted: syncCompleted
};
}]);
这种工厂方法的主要思想是我经常(每个500ms)向后端发送ajax请求并检查某些操作是否完成,以及何时完成我想向控制器功能发送承诺,看起来像这样:
function save( client ) {
clients.addClient( client )
.then( function(response) {
synchronizationStatus.syncCompleted(response.data.CorrelationId);
}, onSaveError)
.then( redirectToList, onSaveError )
.finally( unblock );
}
在backend返回true后我的工厂方法我想在我的控制器中执行其他功能。当然我可以在我的控制器中进行递归,它可以解决这个问题。虽然我必须在许多其他控制器中重用这个递归,所以我想重用这个方法。
答案 0 :(得分:2)
是的,您应该可以这样做,但您需要稍微更改工厂中的代码:
angular.module('module')
.factory('synchronizationStatus', [
'$http',
'apiBase',
'$timeout',
function ($http, apiBase, $timeout) {
var service_url = apiBase.url;
function waitSyncCompletion( correlationId ) {
return checkSync (correlationId)
.then(function(response){
if (response.data) {
return "all done!";
}
return $timeout(function() {
// check again
return waitSyncCompletion(correlationId);
}, 500);
});
}
function checkSync( correlationId ){
var query = '...'; // determine query
return $http.get(service_url + query);
}
return {
waitSyncCompletion: waitSyncCompletion
};
}
]);
然后在您的控制器中,您需要使用return
,以便等待操作完成:
function save( client ) {
clients.addClient( client )
.then( function(response) {
return synchronizationStatus.waitSyncCompletion(response.data.CorrelationId);
})
.then(function (result) { console.log(result); })
.then( redirectToList )
.catch( onSaveError )
.finally( unblock );
}
答案 1 :(得分:-1)
使用Angular的$q来使用自定义延迟(承诺)。确保在工厂中注入$q
依赖项并在工厂开始时创建延迟:
var deferred = $q.defer()
在承诺必须解决的位置,添加:
deferred.resolve();
并确保在syncCompleted
函数底部返回承诺:
return deferred.promise;
此外,如果您还想要错误处理,可以添加deferred.reject()
。此外,如果需要,您可以向reject()
和resolve()
添加参数。
作为替代方案,您可以在不使用$q
的情况下实现相同的目标。 $timeout()
也会返回一个承诺,如果你在给then()
的回调函数中返回一个承诺,它将会'替换''父'承诺。