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 时,该承诺将被解析。