Обещания Энгулера вводят в заблуждение тем, что они не всегда вызываются асинхронно
Недавно я отлаживал некоторые вещи, связанные с обещаниями в angular.js, и заметил, что angular помещает разрешения обещаний в цикл evalAsync, как показано на этой диаграмме. У меня сложилось впечатление, что обратные вызовы обещания всегда выполняются асинхронно (как новое событие в очереди событий). Однако с помощью механизма 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);
Разве это не вводит в заблуждение?
1 ответ
Не уверен, что я назову это обманчивым или нет. Факт это:
- Обратные вызовы Promise всегда выполняются асинхронно. Их никогда не вызывали до
.then()
они были переданы в возвращение.
В большей степени они даже никогда не вызываются из пользовательского кода - в стеке есть "только код платформы", как указано в спецификации Promises/A+. - Не гарантируется, что каждый асинхронный обратный вызов выполняется в свою очередь цикла событий. Не требуется, чтобы два обратных вызова не совместно использовали один и тот же цикл цикла событий. В конце концов, они не могут различить это в любом случае.
В вашем случае Angular квалифицируется как код платформы, который использует свой собственный "цикл обработки событий" - цикл дайджеста.