angularjs-控制器中从未解析承诺

angularjs-控制器中从未解析承诺,angularjs,Angularjs,在我的控制器里,我得到了另一个服务的承诺。我在其中添加了一个'then'子句,但从未调用'then' 看到这个扑通声:() “fakeLongRunningPromise”创建一个承诺,该承诺在2秒后自行解决 在控制器本身中,一旦承诺得到解决,我会向控制台发送一个注释 我可以看出承诺正在被解析,因为它输出到控制台的“解析承诺”。为什么不输出“承诺已解决” 认为承诺可能“超出范围”,因为控制器返回?承诺解析的结果在$digest循环内异步传播。因此,只有在进入$digest循环时才会调用在then

在我的控制器里,我得到了另一个服务的承诺。我在其中添加了一个'then'子句,但从未调用'then'

看到这个扑通声:()

“fakeLongRunningPromise”创建一个承诺,该承诺在2秒后自行解决

在控制器本身中,一旦承诺得到解决,我会向控制台发送一个注释

我可以看出承诺正在被解析,因为它输出到控制台的“解析承诺”。为什么不输出“承诺已解决”


认为承诺可能“超出范围”,因为控制器返回?

承诺解析的结果在$digest循环内异步传播。因此,只有在进入$digest循环时才会调用在
then
中注册的回调。
setTimeout
执行“AngularJS世界之外”,因此不会触发回调

解决方案是使用
Scope.$apply
$timeout
服务。以下是带有$apply的版本:

      window.setTimeout(function() {
        console.log("Resolving promise");
        $scope.$apply(function(){
          deffered.resolve("worked");
        });
      }, 2000);

下面是一个固定的plunk(JavaScript):

我使用了
$timeout
而不是
setTimeout
,它可以工作:

 # Resolve the promise after 2 seconds
  $timeout( ()->
    console.log "Resolving promise"
    deffered.resolve ("worked")
  , 2000)

感谢Pawel,我的实际案例没有使用setTimeout,但它需要一个$digest循环这一事实很有趣——这是我没有想到的。可能是问题的一部分。所以每次使用(比如)$http.get(),除非有摘要,否则不会触发结果承诺?看起来很奇怪。$http调用$digest cycle(通过调用$apply),DOM事件和$timeout服务也是如此。因此,只要您在AngularJS世界中解决了承诺,结果就会立即传播,而无需手动调用$apply。因此,实际上需要$digest来传播解析/拒绝结果,但大多数情况下您看不到这一点,因为AngularJS负责调用$apply.Huh。在我的实际情况中,我使用的是$http,但控制器函数中的承诺无法解决。只有将它们放入$scope函数中,它们才能解析。我会继续努力,但我认为$digest是关键。再次感谢。好的ol'$scope.$apply。将我新的连锁承诺包装在$apply中,它就像一个符咒。呸@Roy,我真的不清楚为什么在使用$http时需要使用$apply-如果我理解正确,通常不需要这样做。如果你能在AngularJS邮件列表上发布你的实际代码,我可以看一下。当然,它是有效的,因为$timeout只是调用$apply的setTimout。换句话说,触发摘要周期的是$timeout服务。但这里的要点是,promise解析的结果只有在您处于AngularJS摘要周期时才会传播。谢谢您的解释。