Концепция async/await
для работы с асинхронным кодом впервые появилась
на платформе .net
в 2011 году. С тех пор разработчики многих языков оценили
удобство этой конструкции и начали ее внедрение. Например, такое произошло
с python
, в котором есть уже встроенная поддержка этого механизма, а также с
языком kotlin
. js
тоже не остается в стороне, и несмотря на то, что этот
механизм находится в стадии разработки (он не утвержден), многие его уже активно
используют в продакшен среде. Хекслет начал использовать async/await
еще
в 2015 году, за что отдельное спасибо babel
.
Использование async/await
очень похоже на то, как мы работаем с генераторами:
const load = async () => {
const a = await Promise.resolve(5);
const b = await Promise.resolve(10);
return a + b;
};
load().then(value => console.log(value)); // => 15
Первым делом необходимо добавить ключевое слово async
перед определением функции.
Это обязательное условие для включения механизма. После вызова функция async
всегда
возвращает Promise
. Внутри функции async
также можно использовать другие асинхронные
операции, ставя перед ними ключевое слово await
. Сами операции должны возвращать Promise
.
По правде говоря, async/await
– это механизм, построенный вокруг и для промисов.
Стоит отметить, что async
функция не является генератором, это обычная
функция, которая выполняется сверху вниз и, в конце концов, может вернуть результат.
Только в отличие от обычного кода на js
, await
дожидается выполнения асинхронной
операции и возвращает ее значение. Как видно, код такой функции плоский и очень
легко читается.
Еще одной особенностью таких функций является то, что наружу всегда будет возвращен
промис, даже если мы возвращаем что-то другое, как в примере выше. Внутри происходит
автоматическое преобразование Promise.resolve(a + b)
. Кстати, это означает,
что код, вызывающий async
функцию, может применять к ней await
, и так
далее по цепочке вверх.
Теперь можно посмотреть на более комплексный пример и сравнить генераторы с async/await
:
import { get } from 'hexlet-http-request';
const getFriends = id => {
return co(function* () {
const link = `http://ru.hexlet.io/users/${id}.json`;
const user = yield get(link);
yield Promise.all(user.friends.map(f => get(f.link)));
});
};
getFriends(5).then(friends => console.log(friends));
Версия с async/await
:
import { get } from 'hexlet-http-request';
const getFriends = async id => {
const link = `http://ru.hexlet.io/users/${id}.json`;
const user = await get(link);
return await Promise.all(user.friends.map(f => get(f.link)));
};
const load = async () => {
const friends = await getFriends(5);
console.log(friends);
};
load();
Здесь можно отметить следующий момент: async/await
не предоставляют возможности
выполнить одновременно несколько асинхронных операций, для этого нужно будет пользоваться
Promise.all
, что логично, ведь await
ждет промис.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты