Обещания Энгулера вводят в заблуждение тем, что они не всегда вызываются асинхронно

Недавно я отлаживал некоторые вещи, связанные с обещаниями в 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 квалифицируется как код платформы, который использует свой собственный "цикл обработки событий" - цикл дайджеста.

Другие вопросы по тегам