All streams
Search
Write a publication
Pull to refresh
30
0.2
Андрей Ч. @Andchir

PHP/Python/JS Full Stack Developer

Send message
«отписался — отпишись»
Ошибка. Правильно: «Подписался — отпишись».
В этом комментарии я приведу два ответа от авторитетных людей в области Angular и RxJS. Выводы делайте сами. Лично мой вывод — RxJS решает одни проблемы и создает новые. Вмеcто того, чтобы расслабиться, ты постоянно в напряжении. У этой библиотеки (методики) есть недостатки (о которых все молчат). Первый человек заботится об облегчении жизни разработчиков, а второй нет. Но второй более авторитетный.

Первый ответ от одного из активных участников команды разработки Angular и NgRx Роба Уормолда:
Вопрос:

Ответ:


Мой перевод:
— В хангаут-разговоре на 27:40 ты говоришь о самоочистке Observables, это происходит всегда?
Необходимо ли нам отписываться, например, в ngOnDestroy в качестве хорошей практики?

— Не видел этот вопрос. Если это последовательность [операция — прим. переводчика] с единичным значением (как http запрос), ручная очистка не обязательна (имея ввиду, что ты подписываешься вручную в контроллере). Если это бесконечная последовательность, ты должен отписаться, что и делает для тебя async pipe.


Второй ответ от разработчика RxJS Бена Леша:

Мой перевод:
— Привет, Бен. Можешь ты мне сказать ВСЕГДА ли мне нужно отписываться от rxjs потоков?
Я не могу найти это в твоих статьях или публичных видео. Спасибо.

— Если это синхронные, или просто несколько значений и это заканчивается (и тебя не волнуют ресурсы), ты можешь забить (если ты лентяй) и не отписываться.

— Но это лучшая практика отписываться.

— Да.


В телеграм чате я обещал человеку под ником Reactive Fox, что если он найдет рекомендацию исполнения контракта «отписался — отпишись» от самого разработчика RxJS, то я принесу ему публичные извинения.
Прошу прощения. Я был не прав, когда говорил, что такой рекомендации в RxJs Нет.
Только плохо, что такой рекомендации нет в документации RxJS.
А вот то что он станет более безопасным и менее подверженным ошибкам — это более серьезный довод в эту сторону.
Это вы пишите, основываясь на личной практике, или это теория? У меня тоже есть не малый опыт. Мне сложно представить, чтобы я пришел в какой-то проект и начал бездумно, не глядя, втыкать какой-то свой код. Обычно в команде пишутся юнит-тесты. Они уберегут от ошибок, которые может сделать другой разработчик в вашем коде. Это и есть своего рода стандарт. А то, что говорите вы, стандартом не является. Приходя в какой-то проект, вы уверены, что разработчик, который делал проект до вас, читал те же Best-practice что и вы? Я думаю это маловероятно. А когда вы видите юнит-тесты, вряд ли Вы будете фантазировать. Прошу ответить на вопрос в первом предложении этого комментария. Только честно.
Читайте обновление #3 внизу статьи. Мне добавить к этому нечего. А если вы с чем-то не согласны, то приводите конкретные цитаты из текста и свои аргументы против.
«Причем тут «преждевременная оптимизация» и безопасный код?»
Не вижу смысла повторять, в статье есть даже дополнение по этой теме. Я не называл отписку преждевременной оптимизацией.
Что проще, потратить минуту на написание одной строчки с unsubscribe/switchMap/takeUntil, чем каждый раз смотреть исходники или вставлять ненужный «отладочный» код и проверять его работу?
На самом деле там всё просто, это же просто JavaScript функции, которые могут быть синхронными и асинхронными. Отписываться от синхронных бессмысленно. Вы же не вызываете «removeEventListener» после того как отфильтровали массив? Там точно такая же логика. Загляните в исходники хотя бы один раз и всё станет понятно.
Это из документации (что происходит при отписке в бесконечном потоке — для понятности переписано):
image
А это из исходников, как создается подписка на событие HTML-элемента (сразу создается функция отписки):
image

В случае асинхронных, конкретно запрос в HttpClient можно в некоторых случаях считать исключением из правил, потому, что поток завершается автоматически. Мне никакие проверки не нужны, проверку я привел для сомневающихся.
Это не преждевременная оптимизация, это нормальная минимизация рисков.
Согласен, отписка это не преждевременная оптимизация. Я писал не об этом. Читайте обновление #3 внизу статьи.
Можете показать, что именно мне необходимо прочитать? Я действительно не вижу, что вы имеете в виду.
Со слов «Т.е. человек перехватил конечный стрим...». Вы изменили логику приложения, поэтому появилась проблема. Это Вы сделали не для какого-то полезного действия внутри программы, а просто для вывода строки в консоль. Тем самым ввели читателя в заблуждение. Существует тысяча способов изменить логику приложения и нарушить его работу. Ещё в районе слов (выше) «Выходит, что „учитель“ был не прав, когда говорил...».

Вы правда считаете… и предлагаете...
Это феноминально. Я пишу «я не предлагаю...», а он мне совсем обратный смысл. Я считаю, что в некоторых случая это вполне нормальное решение. А если вы будете и это за меня решать, то может будете за меня писать код?

Ещё раз. Читаем то, что выделено жирным. Но с вами диалог я заканчиваю. Мы ходим по кругу. Отвечать больше не буду.
В статье вы писали:
И действительно, на его стенде можно увидеть как процессор выполняет ненужную работу (когда я ничего не нажимаю) и как увеличивается расход памяти (изменение небольшое)
А дальше не надо читать? Не вырывайте кусочек и контекста.

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

Что вы пристали к этим отпискам? Разве статья называется «не отписывайтесь»? Нет. Не это главное.
Кстати, в статье я привел пример такой же потенциальной проблемы, которая возникает из-за отписки (в случае если нет блокировки закрытия окна). Но вы это игнорируете, даже не пытаетесь возразить что-то конкретное. Это ли на фанатизм?
Но в отличии от вас, я никого не запугиваю, давая ложную (непроверенную) информацию, я ничего не утаиваю и не говорю, что моему примеру нужно следовать всегда.
И, простите, но вот как раз из-за подобных решений и была написана та статья с примерами: habr.com/ru/post/479732/#comment_21004844
Это только для проверки. Там, откуда я взял этот код (мой код), даже есть комментарий:
github.com/andchir/test-angular-app/blob/master/my-app/src/app/components/good-modal/good-modal.component.ts#L31
Давайте пройдемся по выводам статьи, у меня к ним очень много вопросов.
Так не пойдет. Проходиться нужно не по выводам, а по всему тексту статьи. Тогда многие вопросы отпадут сами собой.
Почему обычный console.log не подходит для демонстрации проблемы?
Что мешает взять готовый пример с проблемой и самому попробовать открыть Developer Tools, запустить профилировку и увидеть все собственными глазами?
Я открыл, проверил и оказалось, что ваши размышления не имеют ничего общего с реальностью. Подробности есть в статье.
Если приведенные мной примеры не являются удачными, то давайте сделаем их лучше? Я только за!
Тут я вам не помощник, потому что по моему мнению вы пытаетесь доказать то, чего нет. Точнее называете утечкой то, что ей не является.
лучше отписываться от потоков, когда они больше не нужны, так как рано или поздно это приводит к проблемам
Приведите конкретный пример. Можно даже из реального проекта. Не надо заставлять читателя поверить вам на слово или придумывать пример самостоятельно. Хватит пустословия! Больше конкретики. Покажите код, где ваша методика предугадывания проблем пригодилась.

Прошу прощения, если что-то пропустил. Позже проверю, пока нет времени.
В вашем конкретном случае — да — нужно. Разве я говорил, что не нужно всегда? Ещё раз перечитайте предыдущий мой ответ. Я выступаю против фанатизма и подмены понятий. Привел конкретные примеры, а вы из меня лепите какого-то нового «гуру», который учит жизни. Я как раз против такого. Читайте выводы внизу статьи.
Я да, я не мою руки, если знаю, что они чистые (не ходил на улицу, не трогал ничего грязного, уже мыл 5 минут назад и т.д.).
Ещё раз. Я не говорил, что отписывать и завершать запрос — это всегда плохо. Я наоборот выступаю против этого «всегда». В статье приведен конкретный пример, когда отписка не нужна. Она там реально не нужна и будет лишним кодом. Не согласны? Вот с этим и спорьте. Не надо мне приписывать то, чего я не говорил.
«а завтра...» — читаем про преждевременную оптимизацию.
«Или еще вариант, наш поток порожден из какой-то другой подписки...» — читаем про SOLID.
Да, я же написал «временно добавить». Это и есть — снять метрики, если в чём-то не уверены, в соответствии с советами Дональда Кнута. Вы с ним не согласны? Если в чём-то не уверены, всегда пишите дополнительный код без проверки?
Если вы в своем пайпе не делаете никакой подписки на события DOM элементов и не добавляете повторы, то он будет конечным. Вы должны держать под контролем свой код. А если вы делаете в своем пайпе всякие мержи, где комбинируете конечные и бесконечные подписки, скорее всего вам стоит задуматься о читаемости и простоте поддержки вашего кода. Почему вы так уверены, что написали не говнокод? Просто потому что это RxJS?
Хотел показать как увидеть завершение потока.
В приложениях с активным использованием rx вы не всегда можете это понять с первого взгляда.
Всегда. 1. Логика. 2. Временно добавить в код проверку:
...
.subscribe({
    next: (res) => {
        ...
    },
    error: (error) => {
        setTimeout(() => {
            console.log(subscription.closed ? 'ERROR - SUBSCRIPTION IS CLOSED' : 'ERROR - SUBSCRIPTION IS NOT CLOSED!');
        }, 0);
    },
    complete: () => {
        console.log('COMPLETED');
    }
});

Information

Rating
2,745-th
Location
Карелия, Россия
Date of birth
Registered
Activity

Specialization

Frontend Developer, Fullstack Developer
Middle
From 200,000 ₽
Python
JavaScript
Angular
PHP
Django
Linux
SQL
MongoDB