0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Несмотря на все удобства, промисы не являются вершиной эволюции. Вспомним минусы, которые они добавляют:</p>
1
<p>Несмотря на все удобства, промисы не являются вершиной эволюции. Вспомним минусы, которые они добавляют:</p>
2
<ul><li>Своя собственная обработка ошибок, которая идёт в обход<em>try/catch</em>. Это значит, что в коде будут появляться оба способа обработки, комбинирующихся в причудливых формах</li>
2
<ul><li>Своя собственная обработка ошибок, которая идёт в обход<em>try/catch</em>. Это значит, что в коде будут появляться оба способа обработки, комбинирующихся в причудливых формах</li>
3
<li>Иногда бывает нужно передавать данные вниз по цепочке с самых верхних уровней, и с промисами делать это неудобно. Придётся создавать переменные вне промиса</li>
3
<li>Иногда бывает нужно передавать данные вниз по цепочке с самых верхних уровней, и с промисами делать это неудобно. Придётся создавать переменные вне промиса</li>
4
<li>С промисами по-прежнему легко начать создавать вложенность, если специально за этим не следить</li>
4
<li>С промисами по-прежнему легко начать создавать вложенность, если специально за этим не следить</li>
5
</ul><p>Все эти сложности убираются механизмом<em>async/await</em>, делающим код с промисами еще более похожим на синхронный! Вспомним нашу задачу по объединению двух файлов. Вот её код:</p>
5
</ul><p>Все эти сложности убираются механизмом<em>async/await</em>, делающим код с промисами еще более похожим на синхронный! Вспомним нашу задачу по объединению двух файлов. Вот её код:</p>
6
<p>А теперь посмотрим на этот же код с использованием<em>async/await</em>. Подчеркну, что<em>async/await</em>работает с промисами:</p>
6
<p>А теперь посмотрим на этот же код с использованием<em>async/await</em>. Подчеркну, что<em>async/await</em>работает с промисами:</p>
7
<p>Эта версия визуально практически не отличается от её синхронной версии. Код настолько простой, что даже не верится, что он асинхронный. Разберём его по порядку.</p>
7
<p>Эта версия визуально практически не отличается от её синхронной версии. Код настолько простой, что даже не верится, что он асинхронный. Разберём его по порядку.</p>
8
<p>Первое, что мы видим, - это ключевое слово async перед определением функции. Оно означает, что данная функция всегда возвращает промис: const promise = unionFiles(...). Причём теперь не обязательно возвращать результат из этой функции явно, он всё равно станет промисом.</p>
8
<p>Первое, что мы видим, - это ключевое слово async перед определением функции. Оно означает, что данная функция всегда возвращает промис: const promise = unionFiles(...). Причём теперь не обязательно возвращать результат из этой функции явно, он всё равно станет промисом.</p>
9
<p>Внутри функции используется ключевое слово await, которое ставится перед вызовом функций, которые, в свою очередь, тоже возвращают промисы. Если результат этого вызова присваивается переменной или константе, то в них записывается результат вызова. Если присвоения нет, как в последнем вызове await, то происходит ожидание выполнения операции без использования её результата.</p>
9
<p>Внутри функции используется ключевое слово await, которое ставится перед вызовом функций, которые, в свою очередь, тоже возвращают промисы. Если результат этого вызова присваивается переменной или константе, то в них записывается результат вызова. Если присвоения нет, как в последнем вызове await, то происходит ожидание выполнения операции без использования её результата.</p>
10
<p>Асинхронность в данном случае (как и в промисах) гарантирует нам, что программа не блокируется в ожидании завершения вызовов, она может продолжать делать что-то еще (но не в этой функции). Но она не гарантирует параллельности. Более того, подряд идущие await в рамках одной функции всегда выполняются строго друг за другом. Проще всего это понимать, если представлять код как цепочку промисов, где каждая следующая операция выполняется внутри then.</p>
10
<p>Асинхронность в данном случае (как и в промисах) гарантирует нам, что программа не блокируется в ожидании завершения вызовов, она может продолжать делать что-то еще (но не в этой функции). Но она не гарантирует параллельности. Более того, подряд идущие await в рамках одной функции всегда выполняются строго друг за другом. Проще всего это понимать, если представлять код как цепочку промисов, где каждая следующая операция выполняется внутри then.</p>
11
<p>А что с обработкой ошибок? Теперь достаточно поставить обычные<em>try/catch</em>и ошибки будут отловлены!</p>
11
<p>А что с обработкой ошибок? Теперь достаточно поставить обычные<em>try/catch</em>и ошибки будут отловлены!</p>
12
<p>Однако, при параллельном выполнении промисов не обойтись без функции Promise.all:</p>
12
<p>Однако, при параллельном выполнении промисов не обойтись без функции Promise.all:</p>
13
<p>Подводя итог, механизм<em>async/await</em>делает код максимально плоским и похожим на синхронный. Благодаря ему появляется возможность использовать<em>try/catch</em>, и легко манипулировать данными полученными в результате асинхронных операций.</p>
13
<p>Подводя итог, механизм<em>async/await</em>делает код максимально плоским и похожим на синхронный. Благодаря ему появляется возможность использовать<em>try/catch</em>, и легко манипулировать данными полученными в результате асинхронных операций.</p>
14
<p>Механизм<em>async/await</em>не отменяет промисы. Он лишь дает удобный интерфейс над промисами, являясь по сути синтаксическим сахаром. Внутри его основы лежат все те же промисы.</p>
14
<p>Механизм<em>async/await</em>не отменяет промисы. Он лишь дает удобный интерфейс над промисами, являясь по сути синтаксическим сахаром. Внутри его основы лежат все те же промисы.</p>