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" - 摘要周期。
我最近一直在调试 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" - 摘要周期。