Поведение в ожидании ценности обещания - PullRequest
1 голос
/ 26 апреля 2019

Я разрабатываю приложение на основе nodejs и электрона, которое должно извлекать данные из базы данных nedb .Я не полностью понял концепцию Обещаний, или мне кажется, что я понял это достаточно далеко, чтобы использовать ее, но она всегда заканчивается путаницей из дюжины вложенных обратных вызовов из-за асинхронного характера обещаний.

Мне известны такие темы, как , этот , и решения, предложенные там.Использование обратных вызовов или метода Promises .then (). Может быть хорошо, если этот путь к коду является «тупиком» (например, обработка ошибок), но для многих последовательных строк он заканчивается бесконечно вложенным кодом.

Я также знаю, что один не должен использовать return await ...(), но я попробовал несколько способов сделать асинхронный метод синхронным.Следующий код вызвал некоторые вопросы:

function getFromDatabase() {
  return new Promise((resolve, reject) => {
    //do something with asynchronous database api
    resolve('database element');
  })
}

async function getSynchronous() {
  var dbElement = await getFromDatabase();
  console.log("before returning: " + dbElement)
  return dbElement;
}

console.log("returned: " + getSynchronous());

Код вернется:

returned: [object Promise]
before returning: database element
  1. Почему тот же объект (dbElement), содержащий строку при ведении журналаон находится внутри функции ('перед возвратом: ...') и содержит обещание при возврате через return функции

  2. Почему возвращенный объект записывается в консоль до тот, что внутри функции?? 1027 *

1 Ответ

2 голосов
/ 26 апреля 2019

Почему тот же объект (dbElement), содержащий строку при регистрации ее внутри функции ('перед возвратом: ...') и содержащий обещание при возврате через возврат функции

Каждая функция async возвращает Promise для своего возвращаемого значения.Поэтому, когда вы возвращаете обычное значение из асинхронной функции - вы получаете обещание для этого значения.

Вполне нормально (пока мы не получим стабильно ожидаемый верхний уровень), чтобы обернуть ваш "основной" код во IIFE (выражение вызова, вызываемого сразу), и использовать там ожидание:

(async () => { // can use await here

  console.log("returned: " + await getSynchronous());
})();

Почему возвращаемый объект записывается в консоль до того, как объект внутри функции будет?

Обещание это значение + время, модель выполнения JavaScript состоит в том, что синхронный код всегда запускается от начала до концаи вы можете «зарегистрировать» только те вещи, которые будут запущены платформой позднее.Таким образом, в этом случае getSynchronous возвращается синхронно, но ожидание происходит после того, как весь синхронный код выполнен.

Хотя в этом коде нет ничего асинхронного - всякий раз, когда вы await что-то, другой синхронный код получает шанс запустить первымтак что если вы измените реализацию того, что вы ожидаете, чтобы быть действительно асинхронным или чем-то асинхронным, вы не получите неприятного состояния гонки в вашем порядке выполнения.Это также верно для способа выполнения обратных вызовов Promise then.

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