Angular 承诺回调和摘要周期

Angular promise callbacks and the digest cycle

AngularJS 中的承诺回调是否保证在摘要周期中被调用?

setTimeout(function () {
  var deferred = $q.defer();
  deferred.resolve();
  deferred.promise.then(function () {
    if ($rootScope.$$phase) {
      //I seem to be hitting this block
      console.log("in digest");
    } else {
      //Could I ever hit this block?
      console.log("not in digest");
    }
  });
});

因为我还不能评论:是的,只要你使用 $q 来创建你的承诺。使用 3rd-party-promise-libraries 你也许能够逃避摘要循环。

顺便说一句,你可以通过一些技巧来编写更优雅的代码:

$q.when([]).then(function(){
  ...
}); 

简答

是*

*长答案

$q 的提供商定义了 nextTick callback to call $rootScope.evalAsync(callback)

引自手册:

The $evalAsync makes no guarantees as to when the expression will be executed, only that:

  • it will execute after the function that scheduled the evaluation (preferably before DOM rendering).
  • at least one $digest cycle will be performed after expression execution.

Any exceptions from the execution of the expression are forwarded to the $exceptionHandler service.

Note: if this function is called outside of a $digest cycle, a new $digest cycle will be scheduled. However, it is encouraged to always call code that changes the model from within an $apply call. That includes code evaluated via $evalAsync.