Как стать автором
Обновить
17
0
Andrew Grekov @thekiba

⚡Making Fast faster

Отправить сообщение
Ещё раз. Читаем то, что выделено жирным. Но с вами диалог я заканчиваю. Мы ходим по кругу. Отвечать больше не буду.


Как минимум некрасиво с вашей стороны вот так поступать. Сначала обращаетесь ко мне публично «человек», обвиняете в том, что я не делал, а потом уходите от ответов на вопросы.

Хоть бы извинились сперва, но да ладно, я обид не держу) Если будет желание пообщаться и разобраться, то всегда можете мне написать в телеграмм.
А дальше не надо читать? Не вырывайте кусочек и контекста.


Можете показать, что именно мне необходимо прочитать? Я действительно не вижу, что вы имеете в виду.

Это был только пример того, что отписываться нужно не всегда. Я там несколько раз сделал оговорку, что не предлагаю так делать везде и всегда и «на всякий случай».


Вы правда считаете, что блокировать UI — это действительно хорошая идея и предлагаете делать это всем?
Так не пойдет. Проходиться нужно не по выводам, а по всему тексту статьи. Тогда многие вопросы отпадут сами собой.


К сожалению, вопросов у меня становится только больше, а ответов на перечисленные выше я не нахожу.

Выше вы сказали:
Я открыл, проверил и оказалось, что ваши размышления не имеют ничего общего с реальностью. Подробности есть в статье.


Тут я вам не помощник, потому что по моему мнению вы пытаетесь доказать то, чего нет. Точнее называете утечкой то, что ей не является.


В статье вы писали:
И действительно, на его стенде можно увидеть как процессор выполняет ненужную работу (когда я ничего не нажимаю) и как увеличивается расход памяти (изменение небольшое)


По поводу примеров:
Приведите конкретный пример. Можно даже из реального проекта. Не надо заставлять читателя поверить вам на слово или придумывать пример самостоятельно. Хватит пустословия! Больше конкретики. Покажите код, где ваша методика предугадывания проблем пригодилась.


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

Из комментария ниже habr.com/ru/post/479732/?reply_to=21007180#comment_21007262:
Кстати, в статье я привел пример такой же потенциальной проблемы, которая возникает из-за отписки (в случае если нет блокировки закрытия окна). Но вы это игнорируете, даже не пытаетесь возразить что-то конкретное. Это ли на фанатизм?


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

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

Я не говорю, что отписываться от подписок RxJS запросов HttpClient не нужно. Я лишь говорю, что бывают случаи когда этого делать не нужно.


На сколько мы можем быть уверены в том, что частные случаи всегда будут неизменяемыми, например «делать отписки не нужно» не превратятся в «делать отписки нужно»?

Сколько потребуется затратить времени на поиск возникшей ошибки, ее описание, локализацию, исправление или полное переписывание всего участка кода?

Будет ли возможность исправить эту проблему, если на уровне архитектуры не закладывалась отмена потоков?

Можете привести примеры таких случаев, когда отписки делать не нужно, свести их к общему правилу, которое можно будет показывать начинающим людям, чтобы быть спокойным за безопасность их кода?

Не нужно подменять понятия. Если вы говорите про утечку памяти, покажите эту утечку. Не ваши бесконечные console.log, а именно утечку. Память в чём изменяется? Время выполнения операции в чём измеряется? Вот это и нужно показать.


Почему обычный console.log не подходит для демонстрации проблемы?

Что мешает взять готовый пример с проблемой и самому попробовать открыть Developer Tools, запустить профилировку и увидеть все собственными глазами?

Если приведенные мной примеры не являются удачными, то давайте сделаем их лучше? Я только за!

Почему вы считаете, что происходит подмена понятий, если описанная в статье проблема решается простым способом — через отписку?

Предвижу возмущенные возгласы подобных «учителей». Они нам обязательно скажут что-то вроде: «ок, утечки памяти нет, но отпиской мы так же отменяем запрос, а значит мы будем уверены, что не будет больше выполняться никакой код после получения ответа от сервера». Во-первых, я не говорю, что отписка это всегда плохо, я лишь говорю, что вы подменяете понятия. Да, то, что после прихода ответа выполнится ещё какая-то бесполезная операция — это плохо, но защититься от реальной утечки памяти можно только отпиской (в данном случае), а защититься от других нежелательных эффектов можно другими способами. Не нужно запугивать читателей и навязывать им свой стиль написания кода.


В чем заключается подмена понятий, когда мы говорим: Необходимо отписываться, чтобы предостеречь себя от ситуаций, когда код будет работать неправильно? Ведь проблема заключается не только в потенциальных утечках памяти и спада производительности, но и в различных сайд эффектах, которые могут произойти.

Я не называю своё решение, которое я применил в тестовом приложении, «серебряной пулей». Наоборот, я призываю дать фронтендеру больше свободы. Пусть он сам принимает решение как ему писать свой код. Не нужно его запугивать и навязывать свой стиль разработки.


В чем именно заключается запугивание и ограничение в свободе, о которой вы говорите?

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

И, простите, но вот как раз из-за подобных решений и была написана та статья с примерами: habr.com/ru/post/479732/#comment_21004844. Вы также можете открыть группу Angular в телеграмме и поискать еще подобных изысков, найдете много интересного.

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

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

Я против фанатизма и преждевременной оптимизации. Этого в последнее время вижу слишком много.


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

Если вам все еще кажется, что это фанатизм, то добро пожаловать в Angular чат. Попробуйте пару дней помочь людям с их вопросами, а потом еще раз посмотреть на всю ситуацию заново.

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

С точки зрения правильности он абсолютно неверен, потому что когда Observable эмитит error или complete, то поток завершается всегда. И все что можно сделать в этом случае, это попросту создать новый поток или ничего не делать.

Исходя из этого, в данном примере мало того, что проверка попросту лишена смысла, так еще и загромождает код, его становится тяжелее писать, читать, понимать и поддерживать. Гораздо более проще было бы, если бы просто отписались.
Когда мы работаем с Observable, то у нас нет понимая на уровне типов является ли поток бесконечным или конечным, холодным или горячим. Более того, бывает, что могут произойти ситуации, когда код будет работать неправильно, потому что забыли отпустить старый ресурс.

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

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

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

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

Сейчас я могу лишь предположить, что вы немного неправильно восприняли основной посыл статьи Почему вам НАДО отписываться от Observable. Основная цель в том, чтобы привлечь внимание к данному явлению и показать некоторые способы решения этой проблемы.

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

И самое главное, takeUntil должен быть в конце:
// Wrong!
pipe(
  takeUntil(read),
  switchMapTo(story)
);

// Ok!
pipe(
  switchMapTo(story),
  takeUntil(read)
);

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность