[英]Chaining promises in angular js
在角度JS我有意想不到的behovier。 我有一個登錄控制器,當我執行登錄功能
$scope.Login = function () {
AuthService.login($scope.credentials).then(function(response){
$location.path('/categories');
},
function(error){
$scope.error_exist = true;
switch(error.ExceptionMessage){
case "201" :
$scope.error = "The emailAddress/password pair don't match an existing member"; break;
case "210" :
$scope.error = "Value cannot be null missing Email Address and/or password."; break;
case "202" :
$scope.error = "The email address you are using isn't confirmed. Please see your inbox for further instructions."; break;
default :
$scope.error = "Error with the server";
}
});
};
發生的事情是AuthService
中的登錄功能被執行然后當它點擊AccountService.GetUserAccounts
,它是服務中的另一個函數,它調用$location.path('/categories');
這是在登錄控制器之后它繼續正常執行我想要的是調用$location.path('/categories');
在AuthService
登錄功能完成后。 她是AuthService
return $http.post(AuthentoctionControllerUrl, credentials).success(function(response){
Session.create(response.Name,response.id, response.UserMail);
AccountService.GetUserAccounts(response.id).then(function(){
var acc = AccountService.getAccounts();
AccountService.SetUserAccount(acc[0], response.UserMail).then(function(){
accIsSet.accSet = true;
},
function(error){
console.log(error);
});
},
function(error){
console.log(result);
});
deferred.resolve(response);
}).error(function(error){
deferred.reject(error);
});
return deferred.promise;
};
還有AccountService
AccountFactory.GetUserAccounts = function(userID){
var deferred = $q.defer();
return $http({method : "post", url:ConfigService.baseUrl+UserURl, data: userID})
.success(function(response){
for(var i = 0; i<response.length; i++)
userAccounts.push(response[i].AccName);
$cookieStore.put("userAccounts",userAccounts);
deferred.resolve(response);
}).error(function(error){
deferred.reject(error);
console.log(error);
});
return deferred.promise;
};
AccountFactory.SetUserAccount = function(accName, userMail){
var deferred = $q.defer();
return $http({method : "post", url:ConfigService.baseUrl+AccountUrl+"?accName="+accName+"&userMail="+userMail})
.success(function(response){
$cookieStore.put('AuthorizationHeader', response.Token);
AccSession.create(response.IsAdmin);
deferred.resolve(response);
}).error(function(error){
deferred.reject(error);
console.log(error);
});
return deferred.promise;
};
AccountFactory.getAccounts = function(){
if(userAccounts)
return userAccounts;
else
return null;
};
她是代碼的編輯,我仍然得到相同的行為。
authService.login = function(credentials) {
return $http.post(AuthentoctionControllerUrl, credentials).success(function(response){
Session.create(response.Name,response.id, response.UserMail);
return AccountService.GetUserAccounts(response.id).then(function(){
return AccountService.getAccounts();
}).then(function(acc) {
return AccountService.SetUserAccount(acc[0], response.UserMail);
}).then(function() {
accIsSet.accSet = true;
});
});
};
AccountFactory.GetUserAccounts = function(userID){
return $http({method : "post", url:ConfigService.baseUrl+UserURl, data: userID})
.success(function(response){
console.log("ssss");
for(var i = 0; i<response.length; i++)
userAccounts.push(response[i].AccName);
$cookieStore.put("userAccounts",userAccounts);
return response;
});
};
AccountFactory.SetUserAccount = function(accName, userMail){
return $http({method : "post", url:ConfigService.baseUrl+AccountUrl+"?accName="+accName+"&userMail="+userMail})
.success(function(response){
$cookieStore.put('AuthorizationHeader', response.Token);
AccSession.create(response.IsAdmin);
return response;
});
};
AccountFactory.getAccounts = function(){
if(userAccounts)
return userAccounts;
else
return null;
};
return AccountFactory;
}]);
調用$ http服務時,返回一個promise。 甲諾有方法。然后(),.catch(),。 最后(),它返回一個承諾為好。 此外, $ http服務的.success()和.error()方法返回一個promise。 因此,通過$q.defer()
創建一個承諾並像這樣解決它是多余的。 如果您想獲得成功的響應值,您只需返回它,如下所示。
更改您的AuthService.login()
以返回如下內容:
return $http.post(AuthentoctionControllerUrl, credentials)
.success(function(response) {
Session.create(response.Name,response.id, response.UserMail);
return AccountService.GetUserAccounts(response.id)
.then(function(acc) {
return AccountService.SetUserAccount(acc[0], response.UserMail);
}).then(function() {
accIsSet.accSet = true;
});
});
和你的AccountFactory
到這個:
AccountFactory.GetUserAccounts = function(userID){
return $http({method : "post", url:ConfigService.baseUrl+UserURl, data: userID})
.success(function(response){
for(var i = 0; i<response.length; i++)
userAccounts.push(response[i].AccName);
$cookieStore.put("userAccounts",userAccounts);
return response;
});
};
AccountFactory.SetUserAccount = function(accName, userMail){
return $http({method : "post", url:ConfigService.baseUrl+AccountUrl+"?accName="+accName+"&userMail="+userMail})
.success(function(response){
$cookieStore.put('AuthorizationHeader', response.Token);
AccSession.create(response.IsAdmin);
return response;
});
};
注意:錯誤處理應該在控制器邏輯中,除非對於需要在工廠/服務本身內更改某些狀態的特殊情況,這將是一個例外。 如果您將捕獲錯誤,請確保返回響應,以便依賴於它的控制器/工廠/服務中的錯誤處理程序仍可以訪問響應。
我在@ryeballar的幫助下成功地解決了這個問題
authService.login = function(credentials) {
var defferd = $q.defer();
$http.post(AuthentoctionControllerUrl, credentials).success(function(response){
Session.create(response.Name,response.id, response.UserMail);
return AccountService.GetUserAccounts(response.id).then(function(acc){
if(acc.data.length !=0)
return AccountService.SetUserAccount(acc.data[0].AccName, response.UserMail);
else
return 0;
}).then(function(data) {
if(data)
accIsSet.accSet = true;
defferd.resolve(response);
});
}).error(function(error){
defferd.reject(error);
});
return defferd.promise;
};
修改了Auth服務以在成功方法結束時解析承諾,因此控制器中的方法將按預期觸發
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.