angular 的 promises 是误导性的,因为它们并不总是被异步调用

is angular's promises misleading in that they are not always called asynchronously

我最近一直在调试 angular.js 中与承诺相关的一些东西,并注意到 angular 将承诺的决议放入其 evalAsync 循环中,如 this diagram 中所述。我的印象是承诺回调总是异步执行的(作为事件队列中的新事件)。但是,使用 angular 的机制,如果任何承诺在摘要循环期间得到解决并且 angular 开始另一个摘要迭代,承诺的回调将在相同的执行堆栈中被调用,因为 evalAsync 总是首先检查队列:

do { // "while dirty" loop
  dirty = false;
  current = target;

  while (asyncQueue.length) {
    try {
      asyncTask = asyncQueue.shift();
      asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals);
    } catch (e) {
      $exceptionHandler(e);
    }
    lastDirtyWatch = null;
  }

  traverseScopesLoop:
  do { // "traverse the scopes" loop
  ...
  } while ((current = next));
...  
} while (dirty || asyncQueue.length);

是不是误导了?

不确定我是否认为这具有误导性。事实是:

  • Promise 回调总是异步执行的。在 .then() 传递给 returns 之前,它们从未被调用过。
    在更大程度上,它们甚至从未从用户代码中调用 - 根据 Promises/A+ spec.
  • 的要求,堆​​栈上有 "only platform code"
  • 不保证每个异步回调都在其自己的事件循环轮次上执行。没有要求两个回调不能共享相同的事件循环周期。毕竟,反正他们也分不清。

在您的情况下,Angular 有资格作为平台代码,它使用自己的 "event loop" - 摘要周期。