Асинхронные запросы или несколько основных ошибок разработчиков
- Категория: Код
- – Автор: Игорь (Администратор)
- Об использовании асинхронных запросов и асинхронности в целом
- Асинхронные запросы не должны приводить к нарушению логики
- Асинхронность не означает экономию ресурсов
- Отсутствие универсальности асинхронных запросов - невозможность вторичного использования
- Вопросы кэширования для асинхронных запросов
- Заключительные слова об использовании асинхронности в программах
Об использовании асинхронных запросов и асинхронности в целом
Асинхронные запросы и асинхронность в целом, или же ajax, вызывают у многих обычных людей, не только разработчиков, ощущение, что их использование автоматически приведет любое приложение к невероятным вершинам и победам на поле брани за производительность. Скорость начнет запредельно расти. Требования к ресурсам быстро упадут. Ну, и вообще вокруг все зацветет и начнет щебетать. Однако, далеко не многие задумываются о косвенных вопросах, которые легко могут привести не только к проигрышу в общем по производительности, но и привнести в программу сложно решаемые ошибки.
Первоначально стоит понять одну простую мысль. Асинхронность - в теории это та же последовательность. Это означает, что все запросы происходят по четко поставленной логике, а не иными способами. Чтобы было проще понять, попробуйте себе представить толпу набежавших школьников к буфету. Выстроятся они в очередь или же будут отпихивать друг друга в попытке урвать заветный пирожок с повидлом не будет иметь значения с точки зрения буфетчицы. Пирожки, как расходились последовательно, так и будут продолжать расходится последовательно. Просто способ выбора того, кто получит пирожок первым будет разный.
Именно поэтому, при использовании асинхронных запросов, так необходимо их рассматривать не в отрыве от происходящего.
Итак, плавно переходим к первой распространенной ошибки.
Асинхронные запросы не должны приводить к нарушению логики
Вы правильно прочитали название этой главы - асинхронные запросы не должны приводить к нарушению логики. При использовании асинхронности, абсолютно всегда необходимо соотносить полученное решение с логикой. Помните, что отсутствие технических ошибок никак не означает правильность выполнения программы, ровно как и верность других аспектов. Так, к примеру, в одной из библиотек использовался чересчур асинхронный подход, что в свою очередь привело к одной простой ошибке. Событие закрытия могло выполниться раньше, чем событие изменения. Чтобы было легче понять, попробуйте себе представить, что вы вначале выключили компьютер, а затем попытались что-то ввести на клавиатуре. Кажется абсурдным, но такие ошибки допускаются сплошь и рядом.
Чтобы не допустить такого рода ошибок, стоит составлять, хоть даже мысленно, последовательные логические цепочки и уже на них проверять используемую модель или решение. Даже если эти цепочки будут элементарными, их все равно стоит проверить. Конечно, на все случаи жизни таких цепочек не напасешься, поэтому есть пара способов, которые помогут вам в этом вопросе:
Первый. Перемешивание. Вы просто берете все асинхронные запросы, которые у вас есть и которые могут исполняться параллельно, и перемешиваете их в случайном порядке, а дальше смотрите, получаются ли какие-либо "забавные" ситуации. Этот способ хоть и сложно назвать универсальным, но даже его порой вполне достаточно. Суть его не только в перемешивании вариантов, а еще и в психологии. Когда человек смотрит с разных сторон на получающиеся ситуации, то он начинает видеть картину в более общем виде.
Второй. Проведение аналогий с ощутимой реальностью. Вы не можете потрогать электроны. Вы не можете представить себе каждый такт процессора. Однако, вы вполне можете представить себе, как течет река или же как движется колесо. Поэтому, проведя аналогию происходящего процесса с чем-то реальным и ощутимым, вы сможете подвергнуть его более глубокому анализу.
Есть и другие способы, но даже этих двух вполне достаточно, чтобы не допустить массы ошибок.
Асинхронность не означает экономию ресурсов
В одной из предыдущих статей про очередь асинхронных запросов уже подымался этот вопрос. Запомните, асинхронность не означает экономию ресурсов. Использование асинхронных запросов может приводить к экономии ресурсов и повышению общей производительности, но никогда асинхронность не будет означать экономию ресурсов (может приводить, но не является равенством).
Чтобы было проще понять, вспомните тот же пример про толпу школьников. Так, если школьники выстроятся в очередь, то количество ушедших пирожков с прилавка буфета может быть больше, чем если они навалятся толпой. Суть заключается в том, что буфетчице не придется отвлекаться на массу посторонних мелочей. Начиная от того, что юнцы могут быть просто нечисты на руку и поэтому необходимо следить за всей продукцией в радиусе их рук, заканчивая тем, что особенно озорные юнцы могут откидывать назад других школьников, даже в тот момент, когда буфетчица уже будет передавать пирожок.
Возвращаясь к техническим моментам, помните, что любой асинхронный запрос практически всегда означает повышение требований к ресурсам. Выигрыш достигается за счет использования ресурсов из времени простоя. Просто представьте себе любое открытие страницы. Даже если вы новичок и слабо в этом понимаете, это не страшно, пример простой. Какой обычно порядок открытия? Вначале разбирается URL, чтобы понять, что пользователь хочет от сервера. Затем проверяется доступ или что-нибудь иное из области безопасности. И только после этого происходит генерация отдаваемого контента пользователю. А теперь задумайтесь. Когда пользователю отдается одна страница, то разбор URL и проверка безопасности происходят один раз. Когда же генерируемая страница запрашивает дополнительные страницы (json и прочее в общем случае можно так же считать страницей, так как это тот же текст, ровно как и html), то этапов разбора URL и проверки доступа будет уже больше.
Примечание: Про экономию за счет отсутствия генерации повторяющегося контента и отсутствия запросов браузера к статическому контенту. В общем случае, реальная экономия достигается только в тех проектах, где на одну сгенерированную страницу приходится действительно много асинхронных запросов. На проектах, где на одну страницу в среднем происходит пара запросов, ajax легко может сказаться на производительности в обратную сторону. И не забывайте, что есть такое понятие, как кэширование, но об этом далее.
Отсутствие универсальности асинхронных запросов - невозможность вторичного использования
Еще одной распространенной ошибкой является масштабное создание уникальных асинхронных запросов, используемых только в одном месте. Когда таких запросов немного, то проблема слабо заметна. Когда же таких запросов становится очень много, то проект начинает наполняться массой "сложностей".
Во-первых, помните, что разделяя страницу на несколько страниц (а ajax именно это и подразумевает), вы увеличиваете сложность модификации логики самих страниц.
Во-вторых, когда задачи уникальных запросов начинают пересекаться, то изменение логики приводит к дополнительным сложностям. Начиная от учета выходных форматов и заканчивая последовательностью доступа к данным.
В-третьих, тестирование и исправление ошибок. Это особенно чувствуется на проектах, где отсутствие универсальных асинхронных запросов - это норма. К примеру, представьте себе, что одни и те же данные с незначительными различиями получаются 15-ю разными способами. Есть и другие моменты.
Суть асинхронности заключается не только в том, что генерация изменяющейся части страницы отделяется от основной страницы, но и так же в возможности вторичного использования информации. Возвращаемые данные в запросе должны быть самодостаточными. Безусловно, полностью избавиться от уникальных запросов не всегда возможно. Однако, даже эти уникальные запросы стоит делать с учетом возможности вторичного использования, ведь вполне возможно, что уникальная/экспериментальная функциональность может стать востребованной и в других частях проекта.
Примечание: Учтите, что асинхронность всегда идет в ногу с декомпозицией. Порой, лучше сделать несколько асинхронных запросов, чем один.
Вопросы кэширования для асинхронных запросов
Достаточно часто обсуждая вопросы использования асинхронных запросов, оставляют без внимания такой важный вопрос, как кэширование данных. Суть проблемы заключается в том, что каждый асинхронный запрос сказывается на количественной характеристике и усложнении процесса кэширования. Если одну полноценную страницу можно сохранить в виде одного отдельного файла или одной строчки в базе данных, то при использовании асинхронных запросов так уже не получится, а это может приводить к дополнительным сложностям и проблемам.
Во-первых. Придется каждый отдельный запрос сохранять так же отдельно, что может сказываться на производительности и требуемых ресурсов. Помните, что файловые системы часто имеют минимальный размер файла, так что 10 Мб чистого текста легко могут превратиться в 50-100 Мб. А 10 000 строк в базе в 100 000. Безусловно, на небольших проектах разница будет слабо заметна, так как объем кэшируемых данных соответствующий, но на средних и больших проектах эта проблема может вылиться в существенную.
Во-вторых. Получаемая стартовая страница будет приводить к нескольким дополнительным запросам, чтобы получить недостающую часть кэшированных данных, что уже само по себе приводит к дроблению данных и как следствие к усложнению общего механизма. Но, это не вся проблема. Дело в том, что когда страница кэшируется целиком, то она кэшируются целиком. Изменились ли какие-то промежуточные данные или нет - не имеет значения, так как страница остается неизменной в кэше. Когда же речь идет об использовании асинхронных запросов, легко может возникнуть ситуация, когда раздробленные данные на кэшируемой странице будут не соответствовать друг другу, ведь кэш асинхронного запроса может измениться раньше, чем кэш страницы (аналогично и в обратную сторону).
Существуют и другие моменты, но даже этих двух вполне достаточно, чтобы понять необходимость в учете этого аспекта.
Заключительные слова об использовании асинхронности в программах
Асинхронность это отличный способ повысить производительность приложений и программ, но только при условии, что асинхронные запросы используются надлежащим образом. Не стоит слепо следовать популяризированным точкам зрения вида "асинхронные запросы это залог быстродействия любого приложения" - успешный опыт одного человека не означает успешный опыт другого. Ведь вполне возможно, что одна маленькая деталь может стать камнем преткновения и причиной массы проблем.
Помните, каждый проект и каждое приложение уникально по своей сути, даже если вы создаете "еще один тысячный сайт или сервис". Поэтому, чем больше аспектов будет учитываться, тем больше вероятность того, что вы создадите действительно быстрое и ресурсоёмкое приложение, которым будет приятно пользоваться как вам, так и другим людям.
☕ Понравился обзор? Поделитесь с друзьями!