← Назад к вопросам

Что должно быть в правой части после await?

2.0 Middle🔥 181 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разбор оператора await в JavaScript

await — это ключевое слово, которое используется внутри асинхронных функций (async function) для приостановки выполнения функции до тех пор, пока Promise (обещание) не будет выполнено (fulfilled) или отклонено (rejected). После await в правой части может находиться несколько типов значений, но их поведение всегда сводится к работе с Promise.

Что может находиться после await?

1. Promise (обещание)

Это наиболее частый и прямолинейный случай. await "ждёт" разрешения (settlement) Promise: если Promise выполняется успешно (fulfilled), await возвращает его результат (value); если отклоняется (rejected), генерируется исключение.

async function fetchData() {
    // Ожидание разрешения Promise, возвращаемого fetch
    const response = await fetch('https://api.example.com/data');
    const data = await response.json(); // response.json() также возвращает Promise
    return data;
}

2. Thenable объект (объект с методом .then())

await работает не только с нативными Promise, но и с любым объектом, имеющим метод .then() (соответствующий спецификации Promise/A+). Это позволяет использовать await со сторонними библиотеками, реализующими свои аналоги Promise.

// Пример с jQuery Deferred (thenable объект)
async function waitForJQuery() {
    const deferred = $.Deferred();
    setTimeout(() => deferred.resolve('Done!'), 1000);
    const result = await deferred; // await работает, так как deferred имеет .then()
    console.log(result); // 'Done!'
}

3. Любое не-Promise значение

Если после await стоит значение, которое не является Promise или thenable объектом, JavaScript автоматически оборачивает его в уже выполненный Promise (Promise.resolve(value)). Это позволяет использовать await единообразно, даже если функция может возвращать как асинхронные, так и синхронные значения.

async function example() {
    const num = await 42; // Не Promise, будет обёрнут в Promise.resolve(42)
    const str = await 'Hello'; // Аналогично
    const bool = await true; // И так далее
    
    console.log(num, str, bool); // 42, 'Hello', true
    return 'All done';
}
// Это эквивалентно:
async function equivalent() {
    const num = await Promise.resolve(42);
    // ...
}

4. Вызов асинхронной функции (async function)

Асинхронные функции всегда возвращают Promise. Поэтому вызов такой функции после await — это частный случай работы с Promise.

async function innerAsync() {
    return 'Result from inner';
}

async function outerAsync() {
    const result = await innerAsync(); // Ожидание Promise, возвращённого innerAsync
    console.log(result); // 'Result from inner'
}

5. Вызов синхронной функции, возвращающей Promise

Это самый распространённый сценарий на практике: функции, возвращающие Promise (например, fetch, fs.promises.readFile в Node.js, setTimeout с обёрткой и т.д.).

async function readFile() {
    const fs = require('fs').promises;
    const content = await fs.readFile('file.txt', 'utf-8'); // fs.readFile возвращает Promise
    console.log(content);
}

Ключевые особенности поведения await

  • Приостановка и возобновление: await приостанавливает выполнение текущей асинхронной функции, но не блокирует основной поток JavaScript. Другие операции (обработка событий, таймеры, другие асинхронные задачи) могут выполняться.
  • Обработка ошибок: Если Promise после await отклоняется (rejects), генерируется исключение. Его необходимо перехватывать с помощью try/catch.
async function riskyOperation() {
    try {
        const data = await fetch('https://invalid-url');
    } catch (error) {
        console.error('Fetch failed:', error); // Перехват ошибки сети или отклонённого Promise
    }
}
  • Преобразование синхронных ошибок: Если после await возникает синхронная ошибка (например, в выражении), она также преобразуется в отклонённый Promise.
async function willThrow() {
    const value = await (() => { throw new Error('Sync error!'); })();
    // Синхронная ошибка будет "обёрнута" в отклонённый Promise
}

Важные нюансы

  • await работает только внутри async функций (кроме top-level await в модулях ES2022+).
  • Не используйте await без необходимости для не-Promise значений, так как это добавляет микротаску в очередь событий и может неоптимально сказаться на производительности.
  • Параллельное выполнение: Для параллельного ожидания нескольких Promise используйте Promise.all().
async function parallel() {
    // НЕПРАВИЛЬНО (последовательное выполнение)
    // const a = await fetchA();
    // const b = await fetchB(); // Начнётся только после fetchA

    // ПРАВИЛЬНО (параллельное выполнение)
    const [a, b] = await Promise.all([fetchA(), fetchB()]);
}

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

Что должно быть в правой части после await? | PrepBro