苦苦挣扎于AngularJs JavaScript的异步性质

时间:2015-08-17 20:49:24

标签: javascript angularjs asynchronous

我有以下代码

if (testNavigation() && $scope.selections.somethingChanged) {
    return false;
}

在testNavigation中我调用模态对话框,如果我在该对话框中回答“确定”,我将somethingChanged重置为false。我的问题是,当执行代码时,testNavigation和modal对话框被旁路并稍后执行,因此我的测试不能正常工作,因为我需要它才能工作。为了使我的逻辑正常工作,我应该改变什么,例如首先调用我的模态对话框,然后在主函数中进行相应的操作?

这是我的testNavigation方法:

var testNavigation = function()
            {                
                if ($scope.selections.somethingChanged) {
                    
                    var modal = $modal.open({
                        controller: function ($scope) {
                            $scope.okClass = 'btn-primary',
                            $scope.okLabel = resourceFactory.getResource('Labels', 'yes'),
                            $scope.cancelLabel = resourceFactory.getResource('Labels', 'cancel'),
                            $scope.title = resourceFactory.getResource('Labels', 'unsavedChanges'),
                            $scope.message = resourceFactory.getResource('Messages', 'unsavedChanges');
                        },
                        templateUrl: '/app/templates/modal'
                    });

                    modal.result.then(function () {
                        
                        $scope.selections.somethingChanged = false;                      
                        
                    });
                }
                
                return true;
            }

我会尝试添加更多细节。我在Index页面控制器中有LoadView()和New()函数。在这两个函数中,我需要执行以下操作:

如果$ scope.selections.somethingChanged = false我需要继续逻辑。

如果$ scope.selections.somethingChanged = true我需要弹出一个模态对话框,询问我是否要继续并取消我的更改或保持当前页面。如果我回答是,我想继续逻辑。

所以,这就是单独的testNavigation函数的目的。在每个函数调用是顺序的语言中,这将按照我的意图工作。但它在AngularJS / JavaScript中不起作用,我不知道如何让它按照我需要的方式工作。我们用$ q服务尝试了一些想法,但没有得到结果。

2 个答案:

答案 0 :(得分:2)

testNavigation()总是返回一个承诺(或者使用模态的结果,或者当somethingChanged为假并且您不想提出问题时立即返回false。继续执行此操作承诺得到解决:

var testNavigation = function() {                
    if ($scope.selections.somethingChanged) {        
        var modal = [...]
        return modal.result;  // returns a promise that will be resolved when the modal is closed
    } else {
        return $q.when(true); // returns a promise that will be resolved straight away with true
    }
}

// when used:

testNavigation().then(function() {
    ...do stuff...
})

答案 1 :(得分:0)

不知道你的测试是什么样的,这有点困难,但从它的外观来看,你正在创造一种竞争条件。

你调用testNavigation(),它总是返回true, 但是因为$ scope.selections.somethingChanged将来某个时候设置为false, $ scope.selections.somethingChanged可能在评估结束之前没有完成 - 所以当你在testNavigation中将$ scope.selections.somethingChanged设置为false时,当执行第二个if时,它可能是也可能不是:

if( testNavigation() &&  // returns true no matter what.
    $scope.selections.somethingChanged // this is changed with a promise within testNavigation. that promise could either complete or not complete before this is evaluated with the if.
  ){
    return false;
}

var testNavigation = function() {
  if ($scope.selections.somethingChanged) {

    var modal = $modal.open({
      // details
    });

    modal.result.then(function() {
      // this is async and could take place any time between {locationA} and never.
      $scope.selections.somethingChanged = false;
    });
  //{locationA}
  }

  return true;
}

我可以想象在测试中产生一些奇怪的结果。