Comments 18
Typescript дописывает ; при компиляции в js, если вам не доплачиваю за ; результат будет одинаковый.
С каких пор это порицается? Пунктуальная нетерпимость какая-то) На всекий случай предостерегаю вас от захода в некоторые открытые репозитории и документации этих компаний https://standardjs.com/#who-uses-javascript-standard-style
Странно видеть ссылку на JS-стайл в контексте статьи по TS...
Тем более линтер может нарисовать эти ; за вас, а публиковать в статье код, не видевший линтера, таки моветон.
Разве этот комментарий не является эттм самым выставлением?
Вопрос по языку: зачем после Promise написали обобщённый тип <T>, если он больше нигде не упоминается? Я думал, это нужно, чиобы обрзначить, что на выходе или у какого-то параметра такой же тип, как на входе, но здесь ни один параметр не имеет тип T и на выходе его нет.
Ошибка же, там дожен был быть unknown
или any
на худой конец.
А, это какой-то обёрнутый в скрытую логику тип данных TS, которому нужно передать, что будет после разрешения промиса?
const runAsyncFunctions = async () => {
try {
const employees = await fetchAllEmployees(baseApi)
Promise.all(
employees.map(async user => {
const userName = await fetchEmployee(userApi, user.id)
const emails = generateEmail(userName.name)
return emails
})
)
} catch (error) {
console.log(error)
}
}
вы тут await
перед Promise.all
забыли. Без него всё насмарку.
upd1. и ещё забыли return
, иначе какой смысл писать return emails
.
upd2. и скорее всего нужен переменная названа криво, т.к. email один, должно быть .flat()
а то у вас странный список email[][]
получается :-)email
(без s
).
Первый же пример "более менее" не эквивалентен. Первый возвращает свойство data от результата fetch, а второй просто результат.
Ну ребят, ну чесслово, издательский дом... Вы этот текст сюда принесли для того, чтобы на корректорах сэкономить?
В переводе с английского «promise» означает «обещание». В JavaScript промис описывает ожидание того, что некоторое событие произойдет в определенный момент, и ваше приложение полагается на результат этого будущего события при выполнении определенных других задач.
...
Заметили паттерн? Первая очевидная вещь, которую нужно отметить – второе событие полностью полагается на первое. Если будет выполнено обещание, заложенное в первом событии, то выполнится и следующее событие. Промис в том событии либо выполняется, либо не выполняется, либо остается в подвешенном состоянии.
...
Мы объявили
promise
при помощи ключевого словаnew + Promise
, где промис принимает аргументыresolve
иreject
. Теперь давайте напишем промис, выражающий события из вышеприведенной блок-схемы.
...
Теперь можно сцепить промисы, что позволяет выполнять их последовательно с применением
.then
. Эти функции похожи на обычный человеческий язык: сделай так, а затем вот это, а потом то и так далее.
Шел 16-й (шестнадцатый) абзац пространной статьи об асинхронном программировании в TS, но до сих пор ни разу не было упомянуто, чем все эти городки с Promise'ами отличаются от if/then/else.
Мы рассказали про порядок выполнения промисов, про то, как их chain'ить, трижды привели косячные примеры кода, определили зависимость выполнения одних промисов от результатов других...
Бывает так, что необходимо параллельно или последовательно выполнять сразу множество обещаний.
20-й абзац... уже где-то почти совсем рядом...
Представьте, к примеру, сто нужно выбрать список из 1 000 пользователей GitHub, а затем сделать дополнительный запрос с ID, чтобы выбрать для каждого из них аватарки. Совсем не обязательно вы захотите дожидаться завершения этих операций со всеми пользователями в последовательности; вам нужны только все выбранные аватарки. Мы подробнее поговорим об этом ниже, когда будем обсуждать
Promise.all
.
Нет, блин, опять какую-то фигню написали. Каким боком Promise.all помогает "не обязательно ... дожидаться завершения этих операций со всеми пользователями в последовательности" - решительно непонятно. Он же, вроде, и нужен для того, чтобы всенепременнейше дождаться прямо конкретно всех, без исключения?
Теперь, когда вы в общем и целом поняли, что такое промисы
Нет, все еще решительно не понимаю... Так ни разу слов "асинхронное выполнение" и примеров, хотя бы как-то с оными связанных, и не встретил. А так-то 25-й абзац уже...
Синтаксис Async/await удивительно прост при работе с промисами. Он предоставляет простой интерфейс для чтения и записи промисов, причем, таким образом, что они кажутся синхронными
Ребят, вы весь текст до этого ни разу не сказали, что промисы - асинхронные! Ну камон, вы чо, блин?
Даже если пропустить ключевое слово
Promise
, компилятор обернет вашу функцию в немедленно разрешаемый промис.
Ну вот может у меня компилятор какой-то не такой, но конкретно мой компилятор ничего ни во что оборачивать не стал. Он просто вывалил мне ошибку и ничего собирать не стал. И я даже с ним согласен, я бы тоже не стал.
Конструкция
async/await
всегда возвращаетPromise
Ну нет же, право слово. async-функция всегда возвращает Promise, а await всегда дожидается, пока он зарезолвится. А что такое конструкция async/await - решительно непонятно. Например, можно объявить async функцию, и не await'ить ее. А await вполне себе используется не только в вызовах async-функций, например, можно `await somePromise` делать, это законно. И это именно потому, что никакой конструкции async/await нет, есть async(асинхронные функции), которые всегда обязаны возвращать промисы, и есть ключевое слово await, которое заставляет текущий поток исполнения дождаться, пока уже возвращенный асинхронной функцией промис зарезолвится.
Таким образом, можно трактовать возвращаемое значение функции async как
Promise
Зачем трактовать-то? Это ж он и есть!
что довольно полезно, когда нужно разрешать сразу множество асинхронных функций
Опачки, здравое зерно! Какой по счету абзац? Я что-то сбился.
Как понятно из названия,
async
сawait
всегда ходят парой.
Блин, вы опять все испортили! Во-первых, вообще не понятно из названия, во-вторых, вообще не обязаны парой ходить... Можно пнуть асинхронную функцию и не дожидаться выполнения - это законно, хоть и не приветствуется (async без await). Можно просто взять готовый промис и дождаться его выполнения, что не только законно, но и в целом очень даже приветствуется (await без async).
То есть, делать
await
можно только внутри функцииasync
Ну да, await может быть использован только внутри async-функции, это да. Но ваше "то есть" предполагает, что это само собой разумеется из сказанного ранее. А это не так... Вообще никакой связи.
Тем более что запрет на использование await'а извне асинхронных функций таки стоит сильно сбоку от "async/await, ходящих парой". Если мы уж пару ищем, то, предположительно, имеем в виду связанную между собой пару из вполне конкретного async в сигнатуре функции и конкретного await'а, который резолва конкретно возвращаемого ей промиса ждет. Ну так вот, сейчас будет срыв покровов: тот await, который ждет разрешения асинхронной функции всегда и гарантировано находится снаружи относительно самой функции.
Вы что, просто из MSDN в произвольном порядке фразы дергаете и гуглотранслейтом их переводите?
const myAsync = async (): Promise<Record<string, number | string>> => {
await angelMowersPromise
const response = await myPaymentPromise
return response
}
Сразу заметно, что этот код выглядит более удобочитаемым и кажется синхронным.
Да он в контексте описанной функции и является синхронным! Ключевое слово async = асинхронное выполнение, а ключевое слово await - это оператор синронизации состояния.
Допустим, например, что у нас лег сервер
Мы должны приостановить выполнение, чтобы предотвратить обвал программы
Что, простите, мы должны предотвратить? Вы же сами говорите, он УЖЕ лег.
В качестве возвращаемого значения ожидаем массив типа
typeof
Странный какой-то тип. У меня, почему-то, есть чувство, что тип с именем typeof в TypeScript объявить нельзя...
Если какое-то исключение ускользнет, то может получиться код, плохо поддающийся отладке, либо даже может быть испорчена вся программа.
Ну, например, ровно как в вашем примере, выброшенный Exception (который не является наследником Error) вполне "испортит всю программу".
Очевидно, нам нужно выполнять эти функции в синхронной манере, но при этом параллельно, чтобы одна функция не блокировала другую.
Вот сейчас вообще не очевидно стало. Вы уж определитесь, синхронно (выполнение инструкций последовательно, в порядке описания в коде программы), или таки параллельно (очевидно, в каком-то другом порядке). Да и вообще, откуда вы это "параллельно" взяли. Асинхронно - правильный термин, параллельность TS вообще никак не гарантирует.
Или про то, чем асинхронность от параллельности отличается, тоже надо рассказать?
Как пишет Mozilla, “
Promise.all
обычно применяется после того, как было запущено множество асинхронных задач, которые должны работать конкурентно, и после того, как пообещали, каковы будут их результаты – чтобы можно было дождаться, пока все эти задачи будут завершены.”
Зачем вы оговариваете Mozilla? Не могли они такую дичь написать! Это просто у вас перевод корявый.
В псевдокоде было бы что-то подобное:
Выбрать всех пользователей =>
/employee
Дождаться всех данных о пользователях. Извлечь
id
от каждого пользователя. Выбрать каждого пользователя =>/employee/{id}
Сгенерировать электронное сообщение для каждого пользователя по его имени
Псевдокод у вас тоже неправильный, последовательный (т.е. синхронный) алгоритм описан. При чем тут Promise.all?
Мы ожидаем отклик (
await
), преобразуем его вJSON
А вы это, простите, зачем делаете? (подсказка: в коде происходит не то, что вы пишете).
Самое важное, о чем здесь нужно помнить – как мы последовательно выполняли код строка за строкой внутри функции
async
с ключевым словомawait
. Мы бы получили ошибку, если бы попытались преобразовать в JSON данные, которых дождались не полностью.
Божечки, что вы несете? Муля, никогда не доверяй важное дело идиотам!
Более интересен фрагмент
runAsyncFunctions
, где все асинхронные функции выполняются конкурентно.
Вот это верно, он, как раз, и есть то, заради чего вся эта муть писалась. Это прям апогей, апофеоз, самая цели статьи и вишенка на торте...
Каждый
fetchEmployee Promise
конкурентно выполняется для всех сотрудников.
... которая в тупую и совершенно бездарно слита буквально через абзац. Как и вся статья...
async
иawait
позволяет писать асинхронный код так, что он выглядит и действует как синхронный
Просто нет слов... Еще раз повторю: async - ключевое слово, означающее асинхронный запуск, await - инструмент синхронизации. await не позволяет писать асинхронный код, await - напрямую команда синхронного исполнения.
Честное слово:Муля Издательский дом "Питер", не доверяй серьезное дело публикацию статей от своего имени на хабре идиотам рерайтерам.
Спасибо! Было полезно прочитать ещё раз другими словами и с понятными примерами, хоть мне пока не нужен Typescript, я изучаю JS
В части Promise.All было уже не так легко понять, но всё равно спасибо 👍
Довольно подробное руководство по промисам и async/await. Но при чем тут тайпскрипт?
Async/await в TypeScript