$evalAsync
方法的角度documentation表示:
$ evalAsync不保证表达式何时出现 执行,只有:
- 表达后将执行至少一个$摘要周期 执行。
通过阅读源代码,我发现此声明不正确。让我解释一下我的观察。应用程序代码可以从异步队列执行,也可以作为监视回调执行。以下是摘要函数的简化相关部分:
// process async queue
while (asyncQueue.length) {
try {
asyncTask = asyncQueue.shift();
// application code can be executed from here - mostly promise callbacks
asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals);
}
}
// process watchers
do {
if ((watchers = current.$$watchers)) {
length = watchers.length;
while (length--) {
try {
watch = watchers[length];
if (watch) {
if ((value = watch.get(current)) !== (last = watch.last)) {
dirty = true;
lastDirtyWatch = watch;
watch.last = watch.eq ? copy(value, null) : value;
// application code can be executed from here - watch callbacks
watch.fn(value, ((last === initWatchVal) ? value : last), current);
通过此实现,您可以看到,如果从异步队列执行的代码中调用$evalAsync
,则代码将保留在while (asyncQueue.length)
循环之前继续执行观察者,因为$evalAsync
推送到asyncQueue另一个回调,条件asyncQueue.length
将返回true
。因此,如果您的代码作为监视回调执行,则上述语句似乎正确仅。
我的理解是否正确?
以下是演示此问题的代码:
$q.when().then(function() {
$scope.$evalAsync(function() {
console.log('from eval async');
});
$scope.$watch('some', function() {
console.log('from watcher');
});
});
此处$evalAsync
内的回调将比$ watch回调更早执行,而我预计它会在至少一次摘要发生后执行。