Conversation
|
Можно пример использования |
|
Вопросы на подумать:
|
|
Ссылка на задачу на доске. Глеб, забирай задачу на себя |
Пример |
|
Да, понимаю, я смотрел код. В общем, опция интересная, и здорово, что она есть. Кому-то она будет полезна. |
services/pub-sub/src/pubSub.ts
Outdated
| /** | ||
| * Getting an instance of a class. | ||
| */ | ||
| static getInstance<ChannelsRecord extends TDefaultChannels>( |
There was a problem hiding this comment.
Может не стоит делать сервис синглтоном? Пусть в месте, где этот сервис используется, отдельно решается быть ему синглтоном или нет.
There was a problem hiding this comment.
Можно убрать instances и getInstance.
Я правильно понял, что использоваться должно вот так:
const pubSub1 = new PubSub<{ message: () => void }>()
const pubSub2 = new PubSub<{ message: () => void }>()
pubSub1.subscribe('message', () => {})
pubSub1.publish('message')
pubSub2.subscribe('message', () => {})
pubSub2.publish('message')
services/pub-sub/src/pubSub.types.ts
Outdated
| ChannelsRecord[ChannelKey] | ||
| >[0]; | ||
|
|
||
| export type ChannelsRecordAdapter<T> = { [K in keyof T]: T[K] }; |
There was a problem hiding this comment.
Зачем адаптер этот нужен? Ты создаешь пакет, у него есть контракт и не надо помогать разработчику выполнять этот контракт. Это допустимо только в случае, когда ты точно знаешь, что есть какой-то существующий популярный контракт и ты его уже адаптируешь.
There was a problem hiding this comment.
Чтобы типизировать инстанс сейчас нужно использовать type, а не interface. Иначе TS ругается, что интерфейс не имеет индексной сигнатуры.
Написал об этом в ридми. Добавил ChannelsRecordAdapter на случай если уж необходимо использовать interface для типизации инстанса.
services/pub-sub/src/pubSub.types.ts
Outdated
| @@ -0,0 +1,14 @@ | |||
| export type TDefaultChannels = Record<string, (data?: any) => void>; | |||
There was a problem hiding this comment.
any заменить на unknown не получилось?
There was a problem hiding this comment.
Пытался, пока не придумал как заменить. Если использовать unknown, то не получится типизировать каналы через дженерик.
Будет ошибка
TS2344: Type 'TPubSubInstance' does not satisfy the constraint 'TDefaultChannels'. Property 'message' is incompatible with index signature. Type '(msg: string) => void' is not assignable to type '(data?: unknown) => void'. Types of parameters 'msg' and 'data' are incompatible. Type 'unknown' is not assignable to type 'string'.
services/pub-sub/src/pubSub.ts
Outdated
| const channelSet = this.channels.get(channel); | ||
| if (channelSet) { | ||
| for (const callback of channelSet) { | ||
| if (callback) { |
There was a problem hiding this comment.
А на promise не надо ли проверить?
There was a problem hiding this comment.
Можно обернуть в промис await Promise.resolve(callback(data));
|
У класса есть instances, но управлять я им не могу. Если я хочу создать новый instance, то это делается через getInstance, что, как мне кажется, не очень очевидно. Я бы либо убрал instances сделав 1 класс = 1 инстанс, либо добавил ручек, чтобы можно было управлять инстансами (например удалить инстанс если он мне больше не нужен). Но мне кажется 1 класс = 1 инстанс будет легче управляемым. |
|
Еще я бы тестил то как хэндлятся ошибки и промисы. Например, у unsubcribe'а нет обратной связи если не удалось найти канал. |
|
@sadcitizen докатит ПР |
|
Убрал синглтон instances, и getInstance(). Поправил типы: убрал Добавил новые методы:
|
| Create a type that defines the channels and their corresponding callback signatures. | ||
|
|
||
| ```ts | ||
| type ChannelsType = { |
There was a problem hiding this comment.
Вот этот тип мне кажется проблемой. С ним у нас есть место, которое должно знать о всех событиях, которые надо обрабатывать. Как будто бы появляется лишняя связь между разными частями приложения.
There was a problem hiding this comment.
Согласен, с глобальным экземпляром есть такая проблема. Тут можно использовать pub-sub только внутри модуля, если это возможно. Или не типизировать глобальный экземпляр и делать адаптер в каждом модуле.
|
Надо посмотреть @sadcitizen |
Паттерн Publish/Subscribe (Observer).
Реализовал через не строгий класс-синглтон, чтобы можно было создавать несколько экземпляров класса с уникальным ключом.
Добавил возможность типизировать инстанс класса.