Pull to refresh
28
0
Роман Теличкин @Telichkin

✍ Software Creator

Send message

window.SENTRY.captureEvent -> import('/sentry').then({captureEvent} => ...), если быть точным, я думал это и так понятно.

Тогда можно использовать абсолютно любой подход, ленивая загрузка будет из коробки :)

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

Что такое этот ваш доменный код в разрезе фронтенд-приложений? Если что, синюю книжку Эванса читал, DDD в реальных проектах видел (не понравилось).

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

Нам же во фронте нужно сфетчить данные, трансформировать их в удобные для отображения структуры данных, сгенерить из структур html, мутировать эти структуры в зависимости от действий пользователя, трансформировать в формат, понятный бэку, и отправить по сети. Попытки с умным лицом засовывать в эту цепочку какие-то "сложные" вещи обычно оборачиваются проблемами для проекта. Лучше смириться с тем, что с точки зрения классического программирования мы -- как фронтендеры -- реализуем в основном довольно простые алгоритмы, но у нас есть свои интересные сложности в работе, просто они немного в другой плоскости: реализация удобных кастомных селектов, которые будут работать во всех браузерах; вёрстка страниц, которая на всех разрешениях выглядит хорошо; минимизация потребления ресурсов, чтобы пользователи на обычных компьютерах не страдали.

Что-то я растёкся мыслею, поэтому повторю вопрос: что такое этот ваш доменный код в разрезе фронтенд-приложений?

EE - достаточно общий и часто применяемый паттерн, глупо говорить что он вообще не нужен. 

Может и нужен, но точно не в таком простом виде. В эвентах должна быть какая-то практическая изюминка. В событийной модели DOM'а есть всплытия событий, в очередях -- возможность подписываться на события по паттерну типа on('form-*-changed', doSomething). Но когда события добавляются только для создания decoupling'а, потому что это "правильно" и Боб Мартин с Мартином Фаулером про это писали, то от такого паттерна только вред

По ссылке вы частично описали тоже самое, что и в этом комменте, но я всё равно не понимаю.

Ну вот есть у вас такой код. Вы пишите, что хотите подгружать аналитику лениво, поэтому нужен декаплинг на эвентах

Но у вас же загрузка тяжёлой библиотеки в бандл будет происходить не в файле ~/features/some/analytics.ts, а где-то, где вы пропихиваете SENTRY внутрь window. Получается, в ленивом импорте здесь не будет никакого смысла.

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

// ~/analytics.ts
export function sendMsg(msg: string) {
  window.SENTRY.captureEvent({ message: msg });
}


// ~/some/model-1.ts
import * as analytics from '~/analytics.ts';

export function submit() {
  // Какой-то код сабмита
  analytics.sendMsg('model-1 form submit');
}


// ~/some/model-2.ts
import * as analytics from '~/analytics.ts';

export function submit() {
  // Какой-то код сабмита
  analytics.sendMsg('model-2 form submit');
}


// ~/some/model-n.ts
import * as analytics from '~/analytics.ts';

export function submit() {
  // Какой-то код сабмита
  analytics.sendMsg('model-n form submit');
}

Зачем тут эвенты? Чем вызов функции из модуля отличается от эвента конкретно в этой ситуации? Эвент здесь просто добавит indirection на ровном месте, который при отладке, фиксе багов или добавлении фичей будет только создавать головную боль.

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

Что значит "никак с критичным процессом не должен быть связан"? Подсказки же всё равно будут связаны с процессом, просто неявно. Типа, если явной связи не видно, то связи вообще нет? Но оно так не работает :) Если под отсутствием связи вы понимаете, что код подсказок может падать, и это никак не должно влиять на процесс оформления, то для таких случаев есть try/catch или catch у промисов. Можно писать как-то так

const noop = () => null;

async function createOrder() {
  // Какой-то важный код
  await tips.showSomeTip().catch(noop);
  // Продолжение важного кода
  await tips.showOtherTip().catch(noop);
}

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

Чем конкретно этот подход хуже эвентов?

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

export const submit = () => {
  // делаем всё необходимое
  analytics.formSubmitted()
}

Чем эта более читаемая запись принципиально хуже decoupled-решения на эвентах?

В посте для аргументов стратегии используется any, в вашем случае тоже придётся пожертвовать типизацией аргументов. Можно пойти немного дальше и сохранить типы:

login(() => loginWithTwitter('123'));
login(() => loginWithLocal('bytefer', '666'));

Зашёл, чтобы оставить похожий комментарий. С самого начала текста создалось впечатление "Я где-то на YouTube смотрел точно такой же ролик". Спасибо за ссылку!


А ещё мне кажется, что этот текст писал не человек, а какой-то алгоритм, как это недавно было с новостями на Hacker News

Вы "отваливаете 100500 денег" на пенсию текущих пенсионеров, а не на свою пенсию в будущем. В России солидарная пенсионная система, а не накопительная

Я не разбираюсь в законах РБ, по-этому ваше утверждение "[Во время обыска в компании] Личные вещи – это все что находится в ваших карманах или ваших руках." для меня немного контринтуитивно.


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

Все же кажется, что к ним пришли из-за этого:


Ранее [PandaDoc] начала кампанию по сбору денег для белорусских силовиков, которые решили сменить профессию

Ссылка на результаты кампании тоже есть в посте: https://www.facebook.com/photo/?fbid=10158723155694592&set=a.10151034658869592

Потому что JSON — это модно. Шутка. Может потому что я описал процесс скраббинга данных и его можно повторить. Товарищи могут в них не верить, я не настаиваю.


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

tmin10 shadek dagen и все остальные, если хотите сами поиграться с данными, то я их вытянул с сайта http://www.vybory.izbirkom.ru и сложил в репу: https://github.com/Telichkin/constitution_data


Файл all_data.json

Интересно, а "Радио Свобода", которая получает прямое финансирование от правительства США[1], будет помечена как "подконтрольная властям СМИ"? В 2019 году они получили 124 миллиона долларов, в 2020 — 87 миллионов долларов.


[1] https://web.archive.org/web/20190320121320/https://www.svoboda.org/a/29830353.html

У вас, видимо, медстрах для ЗП в 200 000 неправильно посчитан. Он должен быть 5.1% * 200 000 = 10 200. У медстраха же нет границы, с которой понижается процент, как у ПФР или соцстраха

Экран у 740 PocketBook-а очень нежный. У нас он треснул через месяц использования, причем никаких внешних повреждений не было: он не падал, на него на него ничего не роняли и не садились. Ридер просто лежал в умеренно набитой женской сумочке.


Если экран треснул — это всегда не гарантийный случай, даже если не было внешних дефектов. Замена экрана стоит 9000р.


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


Четвертый kindle живет у нас с 2011 года, и никакие падения и тем более набитые сумки его еще не смогли сломать.

А почему нативно не написать retry, зачем нужно использовать сторонние библиотеки для базовой функциональности, которая пишется один раз на весь проект?


Если хочется настраивать retry перед каждым запросом:


const delay = ms => new Promise(resolve => setTimeout(resolve, ms))

const asyncRetry = async (asyncFn, { times, delayMs }) => {
  const lastTime = times - 1
  for (let i = 0, i < times, i++) {
    try {
     return await asyncFn()
    } catch (err) {
     if (i === lastTime) throw err
     await delay(delayMs)
    }
  }
} 

Если хочется настроить один раз в момент создания fetch-функций:


const retryable = (times, delayMs, asyncFn) => (...args) => 
  asyncRetry(() => asyncFn(...args), { times, delayMs })

const fetchUser = retryable(5, 2000, async (id) => {
  // fetch logic
}

Иногда кажется, что разработчики за модными библиотеками не замечают возможности языка.

По ссылке написано:


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



И потом давно известен феномен — когда целенаправлено работают на позицию в рейтинге, чисто формально соответствуя критериям.

Это в равной степени относится к каждой стране в рейтинге.

А по данным всемирного банка, государство делает все, чтобы бизнес было вести легче. В 2009 году Россия занимала 118 место в мире по легкости ведения бизнеса, а в 2019 уже 31[1]. По этому показателю Россия обогнала Францию, Италию и Швейцарию.


[1] https://ru.m.wikipedia.org/wiki/Рейтинг_лёгкости_ведения_бизнеса

Все комментаторы, которые пишут, что фильм художественный, а не документальный, вам художественный фильм «Движение вверх» тоже понравился? Лайки обзору BadComedian[1] не ставили?

Уже после двух серий появляется столько «почему», что дальше смотреть сложно:

— Почему в сериале все руководители, даже главврач больницы, показаны дегенератами, которые не врубаются в ситуацию?
— Почему вся молодёжь и простые работяги сразу понимают ужас трагедии?
— Почему женщина физик из Минска так быстро понимает причину аварии и неэффективность способа борьбы с последствиями?
— Почему Хомюк на собрании с Горбачёвым намного уверенней Легасова? Легасов во время своей речи мямлит и неуверенно листает отчёт, и на этой неуверенности оператор делает акцент. Хомюк говорит без запинок, никуда не смотрит, оператор показывает только ее лицо и воодушевленное лицо какой-то пожилой женщины на собрании.
— Почему все что-то делают или под дулом автомата, или за деньги?
— Почему эвакуация начинается только после фразы «сегодня в Германии детям запрещают гулять на улице» и последующего переезда камеры на советских школьников, которые бегут домой на фоне дымящейся АЭС?
— Почему зритель за точно восстановленным антуражем не замечает клюквы?
— Почему даже после слов режиссёра «We had a general standing philosophy from the beginning, which was: Accuracy is everything to us.»[2] люди продолжают прикрывать все дыры «художественностью» этого сериала?
— Почему люди думают, что Американцы, которые так радовались смерти коммунизма[3], будут показывать настоящий СССР?

[1] www.youtube.com/watch?v=1nX0kF2UwDc&feature=share
[2] www.vice.com/en_us/article/j5wbq4/craig-mazin-interview-about-chernobyl-hbo-miniseries-on-how-accurate-and-what-really-happened
[3] youtu.be/c0QG_UvLkJo?t=19m

Жаль, что Erlang довольно низкоуровневый в плане реализации ООП. Если в Smalltalk для обработки сообщения объектом достаточно создать метод с нужным селектором, то в Erlang принято сначала писать сервер, который умеет обрабатывать определенные сообщения, а потом клиент для этого сервера.


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

А лучше не медитировать, а пописать на Smalltalk в котором между написанием программы и ее рантаймом нет никакой разницы.


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


В современных "динамических" языках информация о "типах" доступна только в рантайме. Так как в этих языках динамичность осталась только в рантайме, но момент написания все еще статический (текстовые файлы), то создается mismatch.


Smalltalk — совсем другой фрукт. Он делает динамическим не только способ работы системы как таковой, но и принцип работы человека с системой. В Smalltalk нет файлов. Кент Бек по этому поводу сказал "I mean, source code in files; how quaint, how seventies!". Да, в Smalltalk исходный код — это текст, но он находится не в файлах.

Пробовали клавиатуру Fleksy?

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity