【问题标题】:How to make a function wait for promise and return synchronously?如何使函数等待承诺并同步返回?
【发布时间】:2015-10-28 23:03:03
【问题描述】:

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

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

$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() 函数只是从用户登录或注销时设置/取消设置的内部布尔值返回真或假值,一切正常。

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

我曾尝试使用 Promise 来处理这种情况,但它产生了意想不到的结果,因为 event.preventDefault() 调用不会立即被调用(仅在 Promise 解决后),此时 $state 已经改变了。至少这会导致 UI 在发送到登录屏幕之前短暂闪烁,并且在某些情况下,其他 $states 在加载时会进行自己的服务器调用,这会失败和/或导致浏览器提示用户进行基本授权(用户名/密码)。

这不起作用:

$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;
    }
};

但我不知道如何做到这一点。

【问题讨论】:

  • 这个的解决方案(不是sync - 而是这个问题的解决方案)可以在这里找到stackoverflow.com/a/26702638/1679310
  • 不是你不想想要这样做,而是你不能这样做。
  • 让你的方法总是返回一个被解析为真或假的承诺。
  • @RadimKöhler - 我想这正是我想要的,谢谢!
  • @BrianMedendorp 很高兴看到这一点!享受强大的 UI-Router ;)

标签: angularjs angular-ui-router promise


【解决方案1】:

看起来我正在寻找这里发布的解决方案:@RadimKöhler 的Confusing $locationChangeSuccess and $stateChangeStart

【讨论】:

  • 似乎有点可笑,虽然对你来说这可能是解决方案,但其他人刚刚对我的解决方案投了反对票......
猜你喜欢
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
相关资源
最近更新 更多