Как стать автором
Обновить

Построение масштабируемых приложений на TypeScript. Часть 2 — События или зачем стоит изобретать собственный велосипед

Время на прочтение8 мин
Количество просмотров15K
Всего голосов 35: ↑30 и ↓5+25
Комментарии16

Комментарии 16

Интересно. Пишите еще. Особенно про управление памятью ).
Думаю, что смайлик тут лишний) Откровений не обещаю, но в асинхронном коде «висячие» ссылки на объекты — дикая проблема. Про нее, как минимум, надо помнить.
А нельзя ли как-то указать что тип Options — это параметрический тип Callback?
А почему класс события параметризируется типом Callback'a? Почему бы не параметризовать его типа данных, с которыми вызывается callback? Типа того:
interface IEvent<Data> { on(fn:(Data) => boolean): ISubscribe { } trigger(d: Data): boolean { } }
Жаль, мне кармы не хватает, чтобы вам ее поднять. Хоть кто-то заметил.

Будет часть 2.5 с исправлением. Там все чуть сложнее, чем вы написали. Сам только утром увидел. Клятвенно обещаюсь больше на ночь глядя сложные статьи не писать.
Нет, пишите; лучшее — враг хорошего и велика вероятность, что статья так и не была бы написана.
А я уж думал, что это какая-то особая типовая дотнет-магия, которую нам, html-программистам, не понять :)
Круто! Сам параллельно прохожу аналогичный процесс разработки.

По коду: лучше бы не писать аннотацию типа там, где она очевидна, например: «public MessagesLoaded: Events.Event = new Events.Event(); », и уж тем паче с обобщенными типами.
В итоге тоже к этому пришел. TS без проблем по правой части выражения вычисляет. В любом случае, спасибо за замечание.
И не только по правой части. Я себе реализовал аналог Linq и при этом получается вот такой типизированный код на TS:

data.document.p.where(paragraphCondition)
    .selectMany(p => p.s.where(sentenceCondition))
    .selectMany(s => s.l)
    .select(l => data.vocabularyItems.firstOrDefault(vi => matchesLexem(vi, l)))
    .where(vocabularyLexem => vocabularyLexem && vocabularyLexem.level < 10 && !alreadyPresent(vocabularyLexem))
    .distinct(vocabularyLexem => vocabularyLexem.descriptor.presentation)
    .foreach(vocabularyLexem => this.vocabularyItems.push(vocabularyLexem));


Где и в последней строчке TS знает правильный тип vocabularyLexem.
Честно говоря, тут уже рождается вопрос про велосипеды и их изобретение. А зачем в TS/JS LINQ? Сто лет есть underscore.js, который все тоже самое делает, типизирован в TS 0.9 и понятен любому фронтэнд разработчику.
Да, наверное :) Я не фронтенд-разработчик, ну и тут дело вкуса, есть и других портов Linq куча.
Не сказал бы, что совсем уж вкуса. При переносе каких-то решений из мира .Net в веб есть один очень серьезный подводный камень — в JS нет типов и, как следствие, рефлексии.

Поэтому если LINQ долежен переноситься вполне адекватно, т.к. это чисто compile time, то многие другие, опирающиеся на рефлексию подсистемы нет. Например, при все схожести шаблонизации ASP.Net MVC c underscore.template по своему подходу, перенести те же практики «в лоб» проблематично из-за невозможности использовать рефлексию для определения типов полей модели, и, как следствие, перехода к куда более тяжелому синтаксису, вместо Html.EditorFor. Хотя о моих размышлениях на эту тему скорее всего как раз следующая статья и будет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории