##// END OF EJS Templates
Added childContainer service to container services, ServiceContaier is destroyable, fixed browser Uuid version
Added childContainer service to container services, ServiceContaier is destroyable, fixed browser Uuid version

File last commit:

r26:0b0a30e050ba propose observables
r146:f3f5c56d3b3e v1.4.0-rc5 default
Show More
observable.md
134 lines | 6.2 KiB | text/x-minidsrc | MarkdownLexer
andrei
spelling fixes
r25 # Observable
Универсальный способ организации потока сообщений. Данный механизм может
использоваться для оповещения об изменениях состояний объектов или для доставки
самостоятельных событий, например, связанных с действиями пользователя.
Является реализацией классического шаблона наблюдателя с возможность сообщить
о коце потока событий. Данная реализация не содержит никаких дополнительных
функций, таких как фильтрация, канал с состоянием, преобразования сообщений и
т.п. Это сделано специально, чтобы реализация оставалась максимально простой.
Пример того, как можно создать последовательность из 10 событий:
```ts
var events = new Observable(async (notify, error, complete) => {
// цикл в котором возникает событие
for(let i = 0; i < 10; i++) {
await delay(1000);
// в качестве данных передается номер события
notify(i);
}
// по окончании последовательности информируем, что событий больше не будет
compelte();
});
// создаем окно с отображением хода событий
var progress = showProgress({ min: 0, max: 9, current: 0});
// подписываемся на события
events.on(
// обработчик очередного события
msg => {
progress.setValue(msg);
cin
the documentation on observables is added...
r26 }.
andrei
spelling fixes
r25 // обработчик ошибки
e => {
progress.showError(e);
},
// обработчик конца потока
() => {
progress.close();
}
);
cin
the documentation on observables is added...
r26
// ожидание следующего события
let firstEvent = await events.next();
andrei
spelling fixes
r25 ```
cin
the documentation on observables is added...
r26 `Observable` можно создавать из событий другого объекта, например, виджета:
andrei
spelling fixes
r25
```ts
cin
the documentation on observables is added...
r26 // клсс
class Canvas {
readonly mouseMove: IObservable<[number,number]>
postCreate() {
// превращаем события виджета в Observable
this.mouseMove = new Observable<[number,number]>((notify) => {
this.mousePad.on('mousemove',(e) => notify([e.clientX, e.clientY]) );
});
}
andrei
spelling fixes
r25 }
```
cin
the documentation on observables is added...
r26 Если объект инкапсулирует в себе `Observable`, он также может сохранить методы
для оповещения подписчиков для дальнейшего их использования внутри класса.
andrei
spelling fixes
r25
```ts
cin
the documentation on observables is added...
r26 // класс, который будет генерировать события местоположения
class PositionTracker implements IDestroyable {
// _nextPosition и _complete будут связаны с position при создании
// экземпляра PositionTracker.
andrei
spelling fixes
r25 _nextPosition: (pos: Position) => void
_complete: () => void
cin
the documentation on observables is added...
r26 readonly position: IObservable<Position>
andrei
spelling fixes
r25
cin
the documentation on observables is added...
r26 // конструктор
constructor(...args: any[]) {
andrei
spelling fixes
r25 super(args);
cin
the documentation on observables is added...
r26 // создаем Observable
andrei
spelling fixes
r25 this.position = new Observable<Position>((notify, error, complete) => {
cin
the documentation on observables is added...
r26 // сохраняем методы для оповещения о новом местоположении
andrei
spelling fixes
r25 this._nextPosition = notify;
cin
the documentation on observables is added...
r26 // метод об оповещении конца потока событий
andrei
spelling fixes
r25 this._complete = complete
});
}
cin
the documentation on observables is added...
r26 // метод для очистки ресурсов
andrei
spelling fixes
r25 destroy() {
this._complete();
super();
}
}
cin
the documentation on observables is added...
r26 ```
## Observable и последовательности
Можно сичтать, что `Observable` это некоторая аналогия итератора только в
парадигме событийного (или реактивного) программировния. Следует также понимать,
что при переходе от синхронного процедурного программирования к событийному так
же меняется и направление управления (Inverse Of Control), что означает
следующее:
* при работе с итераторами клиенты сами определяют момент чтения следующего
элемента последовательности.
* при работе с `Observable` клиенты вынуждены обрабатывать эти события по мере
их поступления и не могут на это повлиять.
Последний пункт можно изменить применив, например, буффер или канал с
состоянием, т.е. очередь, но данные механизмы выходят за рамки простого шаблона
наблюдателя.
```ts
while(1) {
// ожидаем следующее событие, по сути это подписка только на одно событие
let next = await events.next();
// такой цикл может пропускать сообщения, поскольку асинхронная операция
// позволит возобновить создание новых событий, на которые мы не подписаны
await processEvent(next);
// не только асинхронные операции могут привести к пропуску события
// например вызов метода, который приводит к созданию события так же
// приведет к тому, что созданное событие не будет обработано в текущем
// цикле
doSmthAndRiseEvent();
}
andrei
spelling fixes
r25 ```