Что выведет фрагмент с asyncFuncA и asyncFuncB: синтаксис и область видимости?

В задаче на async/await сначала нужно проверить корректность кода: лишняя скобка и недоступная функция мешают запуску раньше разбора очередей событий.

Короткий ответ

Что ответить на собеседовании

В представленном исходнике лишняя закрывающая скобка перед asyncFuncA(), поэтому модуль не разбирается и перечисленные console.log не выполняются. Одного удаления скобки недостаточно: asyncFuncB объявлена внутри asyncFuncA, но вызывается снаружи. Без уточнения исправленного кода единственного порядка вывода нет.

Подробный разбор

Ответ с пояснениями

Условие

Определите вывод следующего фрагмента. В исходнике перед основной частью также импортируется CSS и задаётся содержимое элемента #app; для объяснения ошибок ниже сохранена вся логика функций и очередей.

const asyncFuncA = async () => {
    console.log('1', '?');
    setTimeout(() => console.log('2', '?'), 0);
    Promise.resolve().then(() => console.log('3', '?'));
    const asyncFuncB = async () => {
        setTimeout(() => console.log('4', '?'), 1);
        console.log('5', '?');
        Promise.resolve().then(() =>
            setTimeout(() => console.log('6', '?'), 0)
        );
    };
    const initPromise = new Promise((res) => {
        console.log('7', '?');
        [
            Promise.resolve().then(() => console.log('8', '?')),
            setTimeout(() => {
                res();
            },
            )
        ];
    });
    await initPromise;
    console.log('9', '?');
};
Promise.resolve().then(() => console.log('10', '?'));
await asyncFuncB();
console.log('11', '?');
};
asyncFuncA();
console.log('12', '?');

Ответ для кода как он написан

Перед asyncFuncA(); стоит лишнее };: соответствующего открытого блока в этой точке уже нет. Это синтаксическая ошибка. Среда не сможет разобрать модуль, поэтому перечисленные вызовы console.log из него не выполнятся. Переставлять их в предполагаемый порядок пока неправильно.

Почему недостаточно удалить одну скобку

asyncFuncB объявлена через const внутри asyncFuncA. За пределами этой функции имя недоступно. Если убрать лишнее };, но оставить вызов await asyncFuncB() на уровне модуля, он завершится ReferenceError, если никакого другого такого имени во внешней области нет. Если запустить фрагмент не как модуль, отдельно возникнет проблема с await на верхнем уровне.

В варианте, где исправлена только скобка и код выполняется как модуль, уже поставленная микрозадача с console.log('10', '?') может выполниться; считать это корректным решением исходной задачи нельзя. Исходный текст вообще не прошёл синтаксический разбор.

Как обсуждать задачу на собеседовании

Укажите обе независимые проблемы и уточните, где должен находиться вызов asyncFuncB: внутри asyncFuncA или снаружи после переноса объявления. Эти исправления меняют структуру выполнения. Не стоит молча переносить скобки и приписывать автору один из вариантов.

После согласования рабочего фрагмента разбирают синхронные вызовы, микрозадачи Promise.then, точки продолжения после await и задачи таймеров. Исполнитель new Promise запускается синхронно, а продолжения промисов выполняются позже. Но эти правила применяются только к синтаксически корректной программе.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку