Комментарии 23
Типичная ошибка использования await — в функции convertCurrency есть два запроса (getExchangeRates и getCountries) которые друг друга не блокируют, но второй зачем то ждёт выполнения первого
То есть функция, которая внутри себя работает с, например, двумя асинхронными, может просто вызываться без всяких async/await? А сами асинхронные функции и так отработают по очереди?
Вы уверены? как мне кажется, если не ждать одну или другую, может случится казус, что вторая функция, которую ждали, отработает при том что первая нет. А тут мы уже отдачу делаем…
можно переписать, и выдавать информацию по поступлению, но если цель отдать инфу вместе… посему может есть ошибка в дизайне, но не в использовании await
можно переписать, и выдавать информацию по поступлению, но если цель отдать инфу вместе… посему может есть ошибка в дизайне, но не в использовании await
Promise.all()
Статья, заметьте, про async/await, объясняющая функционал наглядным примером.
Удержание равновесия на мотоцикле можно показать на велосипеде, если цель в постановке примера…
Удержание равновесия на мотоцикле можно показать на велосипеде, если цель в постановке примера…
я статью не читал. обычно при описании await первым делом говорят, что это — те же обещания, только в более удобной форме. соответственно, для понимания работы await нужно знать как работают обещания и какие для них есть полезные функции, та же Promise.all().
достаточно прочитать наименование статьи… ;)
Я не спорю, и Вы и lleo_aha в корне правы.
Однако, это как мне кажеться, как писать в каждой статье «Как написать xyz на PHP», что питон лучше. В корне может и так оно и есть, но это не отменяет права на использование PHP для решения задачи. Так и await/async, как мне кажется более или менее был показан конструкт сей функции автором. Реализация примера для этих целей, второстепенна, если она исчерпывающая.
Я не спорю, и Вы и lleo_aha в корне правы.
Однако, это как мне кажеться, как писать в каждой статье «Как написать xyz на PHP», что питон лучше. В корне может и так оно и есть, но это не отменяет права на использование PHP для решения задачи. Так и await/async, как мне кажется более или менее был показан конструкт сей функции автором. Реализация примера для этих целей, второстепенна, если она исчерпывающая.
если было бы важно выполнять функции паралельно то по моему без Promise.all не обойтись.
можно написать
async function parallel(m){return await Promise.all(m)};
и потом обращаемся
const m=await parallel([getExchangeRate(fromCurrency, toCurrency),getCountries(toCurrency)]);
получим массив из двух ответов
можно написать
async function parallel(m){return await Promise.all(m)};
и потом обращаемся
const m=await parallel([getExchangeRate(fromCurrency, toCurrency),getCountries(toCurrency)]);
получим массив из двух ответов
можете объяснить, чем Ваш пример лучше авторского?
по факту идёт тоже самое, только написано по другому. Или я не прав?
по факту идёт тоже самое, только написано по другому. Или я не прав?
async function parallel(m){return await Promise.all(m)};
А какой смысл в этой функции? Скрыть из кода упоминание Promise? Но асинхронная функция всегда возвращает обещание, поэтому было бы достаточно написать так:
function parallel(m){return Promise.all(m)};
Эффект тот же, но работать будет быстрее, так как не создает совершенно лишнее по смыслу обещание-обертку, которое разрешается после разрешения обещания Promise.all(). Проверял только на NodeJS v8.11.3, возможно, когда-нибудь оптимизатор и такие вещи научится упрощать.
Но на мой взгляд, гораздо лучше вызывать Promise.all() напрямую, без оберток. В любом сколько-нибудь реальном применении async/await все равно придется разбираться с обещаниями, так что скрывать их из кода нет смысла.
Можно обойтись, но выглядит мусорно.
let p1 = prom1()
let p2 = prom2()
let r1 = await p1
let r2 = await p2
Здесь удержание равновесия демонстрируется на трёхколёсном велосипеде, что может дать неверное представление о паттернах асинхронного программирования, ну, или удержания равновесия. Небольшое усложнение в виде Promise.all немного расширит кругозор и покажет, как делать правильнее.
а как в данном случае правильно сделать так чтобы они друг друга не блокировали, но дальнейший код выполнялся только после завершения обоих запросов?
Использовать Promise.all
const convertCurrency = async (fromCurrency, toCurrency, amount) => {
const [exchangeRate, countries] = await Promise.all([
getExchangeRate(fromCurrency, toCurrency),
getCountries(toCurrency),
]);
const convertedAmount = (amount * exchangeRate).toFixed(2);
return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`;
};
async/await
— это те же самые промисы, просто с альтернативным синтаксисом, поэтому вместо await
для каждой отдельной функции можно использовать await Promise.all
.
const convertCurrency = async (fromCurrency, toCurrency, amount) => {
const [ exchangeRate, countries ] = await Promise.all([
getExchangeRate(fromCurrency, toCurrency),
getCountries(toCurrency)
]);
const convertedAmount = (amount * exchangeRate).toFixed(2);
return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`;
};
Upd: Прошу прощения за похожий ответ. На момент публикации моего комментария, других ответов не было, но мой комментарий проходил премодерацию.
я не понимаю зачем для даной задачи использовать асинхрон? зачем все так сложно? можно сделать функцию что приймет валюту и по формуле даст результат при клике на кнопку Результат или создать собитие addEventListener, (что есть вроде тоже асинхроним собитием) и при вводе суми в input слушать его собите изменения значения… без всяких там ожиданий первой под фунции, для виполнения второй под функции
напишите реальний пример, боевой из прода, но простой для чайника, плз)
напишите реальний пример, боевой из прода, но простой для чайника, плз)
Так вот тебе реальный пример из прода в статье. Получение данных из апи. При чем здесь ивентЛисенер? Пока промис не отработает, тебе инфа не придёт. Надо дождаться. Можно ждать колбэками, можно промисами, можно асинками. Просто асинки удобны. Грубо говоря, пока не выполнится первый await, второй будет ждать. Второму надо получить инфу из первого. Без нее он будет работать с undefined. Если я правильно понял пример.
А я вот не понял, почему последний вызов был с конструкцией then, когда как вызов других функций внутри третьей был без них.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Осваиваем async/await на реальном примере