convert to promise 解决http的async特性
convert to promise to solve async nature of http
在我的登录屏幕上,当我单击 "Sign-In" 按钮时它会调用登录功能。它实际上是 ng-submit="login()"。代码在我的 LoginCtrl 控制器中。
function onSuccessfulLogin() {
$scope.failureMessage = "";
$rootScope.mainbody.position = 'absolute';
if (nextState !== null && typeof nextState.name === 'string' && nextState.name !== '') {
console.log("calling nextState ......");
$state.go(nextState.name, nextState.params);
} else {
$state.go('main', {});
}
}
$scope.login = function() {
disableLoginButton();
$rootScope.login = {
goodmsg : true,
errormsg : false
}
$scope.failureMessage = "Signing in Analytics Dashboard ....";
User.authenticate($scope.username, $scope.password, onSuccessfulLogin, onFailedLogin, $scope.persist);
};
我有一个名为 User 的服务,单击上面的登录按钮后我会调用 "authenticate" 函数。在我在 "this.authenticate" 函数中添加更多 HTTP 调用之前,它目前工作正常。我想要发生的是将其转换为 promise,以便在收到所有 HTTP 请求的所有数据时,它会在正确的时间调用 onSuccessfulLogin()。但是,我不确定如何将 "this.authenticate" 转换为 return 承诺。顺便说一句,TokenService 是我制作的 Restangular 工厂。
此外,我想将其转换为承诺的原因是因为我想确保在 ui-router 实例化我将要显示的控制器之前准备好所有数据。
this.authenticate = function(username, password, successCallback, errorCallback, persistData) {
this.removeAuthentication();
TokenService.setResponseInterceptor(function (data, operation, what, url, response) {
if (operation == 'post') {
$rootScope.locationResourceId = response.headers('Location').split('/')[response.headers('Location').split('/').length-1]
}
return response.data;
});
TokenService.one('authentokens').customPOST({'email' : username , 'password' : password}, '', {app : 'baam'})
.then(function(data) {
var userresourceId = data.href.split('/')[data.href.split('/').length-1]
$rootScope.userData = {
isAuthenticated : true,
username : username,
bearerToken : data.token,
expirationDate : new Date(data['expires']),
resourceId : userresourceId,
tokenResourceId : $rootScope.locationResourceId
};
TokenService.one('users').customGET($rootScope.userData.resourceId, { 'token' : $rootScope.userData.bearerToken })
.then(function(jsondata) {
$rootScope.userData.locale = retrieveLocale();
// Set locale via Factory
var currentLocale = CurrentLocaleFactory;
currentLocale.locale = $rootScope.userData.locale;
$rootScope.userData.firstname = (jsondata.firstname == null) || (jsondata.firstname == null) ? '' : jsondata.firstname;
$rootScope.userData.lastname = (jsondata.lastname == null) || (jsondata.lastname == null) ? '' : jsondata.lastname;
var avatar = username.split('@')[0].toLowerCase();
$http.get('assets/json/avatar.json')
.then(function(res) {
$rootScope.userData.gravatarLink = res.data.gravatarLink;
if (persistData === true) {
saveData();
}
if (typeof successCallback === 'function') {
successCallback();
}
}, function() {
$rootScope.userData.gravatarLink = "assets/img/noface.png";
if (persistData === true) {
saveData();
}
if (typeof successCallback === 'function') {
successCallback();
}
})
})
}, function(data) {
if (typeof errorCallback === 'function') {
if (data.error_description) {
errorCallback(data.error_description);
} else {
errorCallback(data.data.message);
}
}
})
};
Return 函数的承诺:
//First return
return TokenService.one('authentokens').customPOST({
'email': username,
'password': password
}, '', {
app: 'baam'
}).then(function(data) {
/* ... */
// Second return inside the success handler
return TokenService.one('users').customGET($rootScope.userData
.resourceId, {
'token': $rootScope.userData.bearerToken
}).then(function(jsondata) {
/* ... */
})
})
然后您的函数将 return 一个将在两个异步调用都已 returned 后解决的承诺。
如果顺序不重要,您还可以使用 $q.all(arrayOfPromises)
,return 是一个承诺,当数组中的所有承诺都已 return 时,该承诺将被解析。
在我的登录屏幕上,当我单击 "Sign-In" 按钮时它会调用登录功能。它实际上是 ng-submit="login()"。代码在我的 LoginCtrl 控制器中。
function onSuccessfulLogin() {
$scope.failureMessage = "";
$rootScope.mainbody.position = 'absolute';
if (nextState !== null && typeof nextState.name === 'string' && nextState.name !== '') {
console.log("calling nextState ......");
$state.go(nextState.name, nextState.params);
} else {
$state.go('main', {});
}
}
$scope.login = function() {
disableLoginButton();
$rootScope.login = {
goodmsg : true,
errormsg : false
}
$scope.failureMessage = "Signing in Analytics Dashboard ....";
User.authenticate($scope.username, $scope.password, onSuccessfulLogin, onFailedLogin, $scope.persist);
};
我有一个名为 User 的服务,单击上面的登录按钮后我会调用 "authenticate" 函数。在我在 "this.authenticate" 函数中添加更多 HTTP 调用之前,它目前工作正常。我想要发生的是将其转换为 promise,以便在收到所有 HTTP 请求的所有数据时,它会在正确的时间调用 onSuccessfulLogin()。但是,我不确定如何将 "this.authenticate" 转换为 return 承诺。顺便说一句,TokenService 是我制作的 Restangular 工厂。
此外,我想将其转换为承诺的原因是因为我想确保在 ui-router 实例化我将要显示的控制器之前准备好所有数据。
this.authenticate = function(username, password, successCallback, errorCallback, persistData) {
this.removeAuthentication();
TokenService.setResponseInterceptor(function (data, operation, what, url, response) {
if (operation == 'post') {
$rootScope.locationResourceId = response.headers('Location').split('/')[response.headers('Location').split('/').length-1]
}
return response.data;
});
TokenService.one('authentokens').customPOST({'email' : username , 'password' : password}, '', {app : 'baam'})
.then(function(data) {
var userresourceId = data.href.split('/')[data.href.split('/').length-1]
$rootScope.userData = {
isAuthenticated : true,
username : username,
bearerToken : data.token,
expirationDate : new Date(data['expires']),
resourceId : userresourceId,
tokenResourceId : $rootScope.locationResourceId
};
TokenService.one('users').customGET($rootScope.userData.resourceId, { 'token' : $rootScope.userData.bearerToken })
.then(function(jsondata) {
$rootScope.userData.locale = retrieveLocale();
// Set locale via Factory
var currentLocale = CurrentLocaleFactory;
currentLocale.locale = $rootScope.userData.locale;
$rootScope.userData.firstname = (jsondata.firstname == null) || (jsondata.firstname == null) ? '' : jsondata.firstname;
$rootScope.userData.lastname = (jsondata.lastname == null) || (jsondata.lastname == null) ? '' : jsondata.lastname;
var avatar = username.split('@')[0].toLowerCase();
$http.get('assets/json/avatar.json')
.then(function(res) {
$rootScope.userData.gravatarLink = res.data.gravatarLink;
if (persistData === true) {
saveData();
}
if (typeof successCallback === 'function') {
successCallback();
}
}, function() {
$rootScope.userData.gravatarLink = "assets/img/noface.png";
if (persistData === true) {
saveData();
}
if (typeof successCallback === 'function') {
successCallback();
}
})
})
}, function(data) {
if (typeof errorCallback === 'function') {
if (data.error_description) {
errorCallback(data.error_description);
} else {
errorCallback(data.data.message);
}
}
})
};
Return 函数的承诺:
//First return
return TokenService.one('authentokens').customPOST({
'email': username,
'password': password
}, '', {
app: 'baam'
}).then(function(data) {
/* ... */
// Second return inside the success handler
return TokenService.one('users').customGET($rootScope.userData
.resourceId, {
'token': $rootScope.userData.bearerToken
}).then(function(jsondata) {
/* ... */
})
})
然后您的函数将 return 一个将在两个异步调用都已 returned 后解决的承诺。
如果顺序不重要,您还可以使用 $q.all(arrayOfPromises)
,return 是一个承诺,当数组中的所有承诺都已 return 时,该承诺将被解析。