JavaScript async/await не ожидает должным образом?

У меня проблема с функциями async/await в JavaScript. Это происходит во внутреннем приложении, для которого я не могу поделиться исходным кодом, но я собрал быстрое общее воспроизведение моей проблемы:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function baz(input) {
  console.log("4");
  await sleep(1000);
  console.log("5");
  return input;
}

async function bar(input) {
  console.log("3");
  return await baz(input);
}

async function foo() {
  console.log("2");
  const foo = await bar("foo");
  return foo;
}

console.log("1");
foo();
console.log("6");

Я ожидаю, что это вернет следующее с ожиданием в одну секунду между 4 и 5:

1
2
3
4
5
6
"foo"

Вместо этого, попробовав это в консоли в Chrome 64.0.3282.167 и Firefox 58.0.2, я получаю следующее:

1
2
3
4
6
undefined
5

Пожалуйста, может кто-нибудь указать, где я ошибаюсь в этом?


person CaptObvious    schedule 18.04.2018    source источник
comment
вы не дождались звонка foo.   -  person Daniel A. White    schedule 18.04.2018
comment
Вы правы, но это все равно не объясняет, почему foo() возвращает undefined, а не "foo".   -  person CaptObvious    schedule 18.04.2018
comment
это потому, что вы нарушили основную цепочку обещаний.   -  person Daniel A. White    schedule 18.04.2018
comment
как вы можете ожидать, что "foo" будет выведено на консоль? как вы думаете, какая строка вашего кода выводит это? все ваши console.log являются числовыми, ни разу вы console.log('foo')   -  person Jaromanda X    schedule 18.04.2018


Ответы (1)


Верхний уровень работает синхронно (как всегда) — он не ждет разрешения foo();, прежде чем перейти к console.log("6");. Оберните вызов foo чем-то асинхронным и await его. Вам также необходимо сохранить возвращаемое значение foo, если вы хотите отобразить его позже:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function baz(input) {
  console.log("4");
  await sleep(1000);
  console.log("5");
  return input;
}

async function bar(input) {
  console.log("3");
  return await baz(input);
}

async function foo() {
  console.log("2");
  const foo = await bar("foo");
  return foo;
}

(async () => {
  console.log("1");
  const str = await foo();
  console.log("6");
  console.log(str);
})();

person CertainPerformance    schedule 18.04.2018
comment
Верно, но это не объясняет, почему он возвращает undefined, а не foo. - person CaptObvious; 18.04.2018
comment
undefined является результатом последнего console.log... введите console.log('hello') в консоли инструментов develoepr... вывод: hello и undefined - person Jaromanda X; 18.04.2018
comment
Оказывается, приведенный мной пример не совсем точно воспроизводит проблему, с которой я столкнулся. Я собираюсь опубликовать этот вопрос, как только создам точную репродукцию. Поскольку предоставленный вами ответ действительно отвечает на заданный вопрос и может помочь людям в будущем, я собираюсь отметить его как ответ. Спасибо! - person CaptObvious; 18.04.2018