Асинхронное программирование имеет тенденцию быть довольно сложным. По мере того, как ваш проект наращивает функциональность, простые операции превращаются в цепочки взаимозависимых выполнений - проблема для создателя, бессонные ночи для его коллеги, пытающегося отладить код.

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

Это может быть не так в вашем проекте, или, может быть, ваша команда просто еще не заметила - лично я хочу, чтобы каждый проект попал в первую категорию. А чтобы свести к минимуму популяцию второй категории - ниже я составляю список самых популярных асинхронных инструментов, которые вы найдете в JavaScript, вместе с их плюсами и минусами. , и небольшие ловушки, которых следует избегать для каждого из них.

Как всегда, я надеюсь, что вы узнаете что-то новое сегодня, сочтете это полезным и используете его для создания чего-то удивительного! 💪

1. Обратные вызовы

C allbacks лежат в основе большинства асинхронных операций. Обратный вызов - это просто функция, переданная в качестве аргумента другой функции. Хотя они довольно неуклюжие и примитивные, вы можете иногда использовать их - чтобы избежать добавления полифилов, в функции Lambda или при игре со старыми дистрибутивами и библиотеками Node.

Обратные вызовы не имеют абсолютно никаких недостатков - проблемы возникают, когда разработчики начинают их использовать, особенно в длинных и сложных цепочках. Обратный вызов - это просто функция. Он позволяет вам делать что угодно, как вы хотите, без каких-либо стандартов. И именно эта свобода вскоре может стать концом вашего проекта.

Как мы можем избежать этого печального конца? Путем c создания стандарта для обратных вызовов - оболочку, модуль или фреймворк. Если вы вынуждены использовать обратные вызовы, убедитесь, что вы позволяете себе использовать их только одним, конкретным и контролируемым способом . Он должен препятствовать вложению обратных вызовов, обеспечивать четкую обработку ошибок и иметь мертвый простой порядок выполнения. То, что вы, вероятно, в конечном итоге получите, будет самодельной версией одного из инструментов из этого списка.

2. Обещания

Если после прочтения этого списка вы в какой-то момент не уверены, какой вариант использовать - использовать обещания. В некоторых случаях могут лучше подойти другие инструменты, но Promises могут быть легко применены к большинству асинхронных проблем в удобочитаемом и поддерживаемом виде .

Обещания - это правильные обратные вызовы. Вы можете легко объединить их в цепочку, отловить ошибки и указать порядок выполнения в полупоследовательном порядке. Они также позволяют создавать циклы, слияние и обработку состояний гонки.

Но это JavaScript - здесь есть загвоздка, иначе было бы неинтересно. Хотя каждая ссылка постоянно побуждает нас объединять обещания в цепочку, мы можем видеть обещание внутри обещания внутри обещания только очень много раз. Вложением обещаний мы не только заставляем код снова выглядеть асинхронным и нечитаемым - мы также заставляем себя вернуться в ад обратных вызовов, из которого они пытались нас вывести.

Если вы когда-либо сталкивались с возможностью вложения промисов, найдите время и придумайте способ использовать метод then или all для связывания выполнения вместо этого - вы можете просто уберечь себя или своего коллегу от огромной головной боли в будущем.

3. Асинхронный режим и ожидание

Сказать «А, но async / await - это всего лишь синтаксический сахар для обещаний» - все равно что сказать «А, но React и его JSX - всего лишь синтаксический сахар». для простого JavaScript ». Оба утверждения верны - но в обоих случаях «одинаковые, но разные» означает всю разницу - в том, как мы структурируем приложение и как в конечном итоге выглядит код.

В то время как Promises позволяют нам писать асинхронный код в полусинхронном порядке, async / await идет дальше и имитирует синхронное выполнение асинхронного кода. Это может значительно улучшить читаемость кода, поскольку ваша кодовая база становится почти полностью последовательной - хотя async / await обычно также требует обещаний, чтобы принести пользу.

Но за все приходится расплачиваться - для Promises мы могли бы легко обрабатывать ошибки с помощью catch, async / await не предоставляет никакого способа обработки ошибок асинхронного кода, который часто дает сбой. Исключения async / await должны обрабатываться так, как если бы они были синхронными - с помощью старого доброго оператора try / catch. А поскольку мы вообще не используем try / catch в JavaScript, вы должны помнить об обработке этих ошибок, иначе они могут серьезно повредить стабильности вашего приложения.

4. Наблюдаемые

В то время как Promise представляет собой одиночное отложенное выполнение, Observable представляет собой поток данных, на который вы можете подписаться, смотреть, объединять, изменять и т. Д. Это позволяет нам моделировать обещания с помощью Observables - аналогичным образом можно моделировать условие if с помощью цикла for. Но Observables не являются обещаниями и не должны использоваться в качестве альтернативы .

Наблюдаемые объекты - великолепный инструмент, когда периодически меняющийся источник данных используется несколькими компонентами приложения. Любые изменения в Observable быстро распространяются на всех слушателей, обеспечивая идеальную синхронизацию и единый источник достоверных данных для всего приложения.

Это также подводит нас к основной проблеме - подписки. Чтобы использовать Observables, вы должны подписаться на них. И если вы не забыли отказаться от подписки, этот Observable останется в памяти, вызывая утечку памяти. Один очень легко упустить из виду, особенно при использовании Observables, например, Promises. Хотя один из них может вызвать незначительный ущерб, если ваше приложение использует новый Observable для каждого сетевого запроса, эти утечки могут быстро расти.

В заключение - надеюсь, я не убедил вас выбрать единственный лучший асинхронный инструмент. Основная цель - понять разницу между предоставляемыми вам инструментами и применить их в зависимости от ситуации. Иногда нам удается создавать целые приложения, используя только один из этих асинхронных помощников - без каких-либо недостатков, - но ставка на знания часто более эффективна, чем ставка на удачу.

Сказав это - Я хотел бы поблагодарить вас за время, потраченное на чтение, я надеюсь, что вы узнали что-то новое сегодня, и я хотел бы услышать ваше мнение в разделе комментариев ниже! s хроничность - нетривиальная тема, и мои комментарии по ее вопросам, безусловно, лишь малая часть того, с чем вы, возможно, сталкивались в своих проектах!

Если вы хотите что-то добавить, поддержать или, может быть, указать, где я был полностью неправ - дайте мне знать в разделе комментариев или напишите мне в Twitter по адресу @thefrontendcat!

Еще раз спасибо,

TheFrontendCat | Студия WTL