Pull to refresh

Comments 18

Режет глаза отсутствие; в конце строк в коде. Не надо свои странные предпочтения выставлять на публику.

Typescript дописывает ; при компиляции в js, если вам не доплачиваю за ; результат будет одинаковый.

С каких пор это порицается? Пунктуальная нетерпимость какая-то) На всекий случай предостерегаю вас от захода в некоторые открытые репозитории и документации этих компаний https://standardjs.com/#who-uses-javascript-standard-style

Странно видеть ссылку на JS-стайл в контексте статьи по TS...

Тем более линтер может нарисовать эти ; за вас, а публиковать в статье код, не видевший линтера, таки моветон.

Знаю проекты на тс, в которых в стайлгайдах и настройках линтера закреплено отсутствие точек с запятой.

Приравнивать несоответствие вашим предпочтениям к недостатку, таки моветон.

ПС. Я люблю ;

Разве этот комментарий не является эттм самым выставлением?

Вопрос по языку: зачем после Promise написали обобщённый тип <T>, если он больше нигде не упоминается? Я думал, это нужно, чиобы обрзначить, что на выходе или у какого-то параметра такой же тип, как на входе, но здесь ни один параметр не имеет тип T и на выходе его нет.

Ошибка же, там дожен был быть unknown или any на худой конец.

А, это какой-то обёрнутый в скрытую логику тип данных TS, которому нужно передать, что будет после разрешения промиса?

Вы правильно пишете, тип Т неоткуда взять. Вместо Promise<T> для результата можно прописать Promise<unknown> , тогда значение которое выдаст await будет иметь тип unknown и не получится его случайно использовать не проверив на соответствие типу (например через type predicate), в отличии от any.

А можно просто не использовать TypeScript например и вообще ничего там не писать )

Смотрите сколько сразу снимается вопросов.

так и в тайпскрипте можно явно не писать тип промиса: ide его выведет из типа аргумента, переданного в resolve

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. и скорее всего нужен .flat() а то у вас странный список email[][] получается :-) переменная названа криво, т.к. 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 - напрямую команда синхронного исполнения.

Честное слово:
Муля Издательский дом "Питер", не доверяй серьезное дело публикацию статей от своего имени на хабре идиотам рерайтерам.

UFO just landed and posted this here

Спасибо! Было полезно прочитать ещё раз другими словами и с понятными примерами, хоть мне пока не нужен Typescript, я изучаю JS

В части Promise.All было уже не так легко понять, но всё равно спасибо 👍

Довольно подробное руководство по промисам и async/await. Но при чем тут тайпскрипт?

Sign up to leave a comment.