Изменяется ли цикл обработки событий после того, как асинхронная функция завершает все асинхронные вызовы? - PullRequest
0 голосов
/ 21 сентября 2018

Давайте рассмотрим этот код:

async function testFunction() {
  // event loop 1 - before any "await", we are still in original event loop, right?
  const result = await Promise.resolve('abc');
  // event loop 2 - we have a new event loop
  return result;
}

// event loop 1
testFunction().then(result => {
  // event loop 2? Or new event loop?
})

Изменяется ли цикл событий снова после того, как функция async выполнила все асинхронные операции? Является ли цикл события прямо перед оператором return таким жекак в операторе then?

И есть ли простой способ проверить это?

Я работаю с некоторым синхронным API, который должен выполняться в том же цикле событий, и яхочу быть уверенным, что это сработает.

РЕДАКТИРОВАТЬ:

Чтобы было понятнее, это пример из реальной жизни:

async function dbTransaction(tableName, transactionMode) {
  const db = await _dbPromise;
  return db.transaction([tableName], transactionMode).objectStore(tableName);
}

Могу ли я использовать транзакцию, возвращенную этой асинхронной функцией?
Некоторая связанная информация MDN:
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#Adding_data_to_the_database

И важная цитата:

Теперь, когда у вас есть транзакция, вам нужно понять ее время жизни.Транзакции очень тесно связаны с циклом событий.Если вы совершите транзакцию и вернетесь в цикл обработки событий, не используя ее, транзакция станет неактивной.

РЕДАКТИРОВАТЬ 2:
Еще одна вещь - ответ да- транзакция может быть использована после const objectStore = await dbTransaction(DB_IMAGE, DB_OP_READWRITE).Только если я жду чего-то еще, я получаю TRANSACTION_INACTIVE_ERR ошибку - что имеет смысл.
Так это по замыслу?Означает ли это, что он действительно находится в той же итерации цикла событий?

1 Ответ

0 голосов
/ 21 сентября 2018

Транзакция действительна только для данного стека.Когда выполняется некоторая асинхронная работа, то есть браузер получает обработчик для indexedDB здесь:

const db = await _dbPromise;

, создается новый стек и он продолжается до конца этой функции.Но кроме основного стека, есть также стек микротак, и в этот стек идут все обратные вызовы от обещаний и наблюдателей.Если обещание помечается как разрешенное при выполнении инструкций из данного стека, оно немедленно вызывается после того, как основной стек очищается, и транзакция там все еще доступна.(Вы можете думать о стеке + микрозадачах как об одном «тике» цикла, после которого javascript передает управление обратно в цикл событий, который решает, что делать дальше).

Итак, в вашем примере:

async function testFunction() {
  // tick 1 synchronous
  const result = await Promise.resolve('abc');
  // tick 1 microtask 1 (up resolved through the execution of the stack)
  return result;
}

// tick 1
testFunction().then(result => {
  // tick 1 microtask 2 (resolved through the execution of microtask 1)
})

Вы можете получить некоторую информацию, проверив панель производительности: enter image description here

Это видео может прояснить, что такое цикл событий и как он работает: https://vimeo.com/254947206

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...