如何使函数等待promise并同步返回?

时间:2015-10-28 14:47:40

标签: angularjs angular-ui-router promise

我知道通常你不想这样做,但是我找到了一个用例,我似乎无法找到任何其他解决方案,并希望我的函数包含一个承诺,等到承诺结算在回国之前。

我正在修改应用程序的身份验证机制,并设置以下代码,以便在$状态更改时仔细检查用户是否已获得授权,如果未经授权,则将其重定向回登录屏幕:

$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {

    // double check that the user is logged in
    if (toState && toState.name.indexOf('auth')<0) {
        if (!user.isAuthorized()) {
            event.preventDefault(); // do not continue to the non-auth state
            user.logout();
            $state.go("auth.login");
        }
    }
});

目前,user.isAuthorized()函数只是从用户登录或注销时设置/取消设置的内部布尔值返回true或false值,并且一切正常。

但是,我们需要将该函数调用到服务器(如果本地布尔值设置为false)以检查用户是否已经有活动会话,然后设置布尔值并返回true。在服务器调用返回之前,我们不希望应用程序执行任何操作,因为它正在检查用户是否应该能够看到UI。

我试图利用一个承诺来处理这种情况,但它有意想不到的结果,因为event.preventDefault()调用没有被立即调用(只有在promise解析之后),此时$ state已经改变。这至少导致UI在被发送到登录屏幕之前短暂闪烁,并且在某些情况下,那些其他$状态在加载时自己进行服务器调用失败和/或导致浏览器提示用户进行基本授权(用户名) /密码)。

这不起作用:

$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {

    // double check that the user is logged in
    if (toState && toState.name.indexOf('auth')<0) {
        user.isAuthorized().then(function(isAuthorized) {
            if (!isAuthorized()) {
                event.preventDefault(); // this does not prevent state change any more
                user.logout();
                $state.go("auth.login");
            }
        });
    }
});

我认为我们需要让user.isAuthorized()函数看起来像这样:

user.isAuthorized = function() {
    if(user.isAuthorizedBoolean) {
        return true;
    } else {
        var returnValue = false;

        // make server side call that returns promise
        user.isAuthorizedServerCheck().then(function(result) {
            if (result === true) {
                returnValue = true;
            }
        });

        // pause execution until promise resolves???

        return returnValue;
    }
};

但我不确定如何做到这一点。

1 个答案:

答案 0 :(得分:0)

看起来像这里发布的解决方案:@ {RadimKöhlerConfusing $locationChangeSuccess and $stateChangeStart正是我正在寻找的。