async/await — не бесплатный. Каждое await создаёт промис, добавляет микротаску в queue и заставляет V8 перестраивать стек. В горячем коде эта стоимость суммируется.
Что происходит на каждое await
- Создаётся
Promise (даже если функция уже завершилась синхронно).
- Текущий фрейм сохраняется в suspend resume frame.
- Микротаска добавляется в queue.
- На след. тике микротаски — фрейм восстанавливается.
Сравнение
function syncFn() { return 42; }
async function asyncFn() { return 42; }
async function bad() {
const x = await 42;
return x;
}
Когда async вреден
- Hot цикл на миллион итераций — НЕ оборачивай шаги в await.
- Чистая синхронная функция — не делай её async «на всякий случай».
- Promise-цепочка из коротких await может быть медленнее единого
.then.
Когда уместен
- Реальный I/O (сеть, ФС).
- Параллельные операции через
Promise.all.
- Читаемость важнее микро-оптимизации.
Подводные камни
for await ... of — последовательно (один await за итерацию).
- Параллельный обход —
Promise.all(arr.map(async ...)).
try/catch вокруг await дешевле, чем .catch цепочка, но всё ещё дороже синхронного.
Источники
См. также