Não pode escolher mais do que 25 tópicos
Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
|
- const contextStack: Observer[] = [];
-
- export class Observer<T = unknown> {
- private effect: () => T;
-
- dependencies: Set<Observable> = new Set();
-
- constructor(effect: { (): T }) {
- this.effect = effect;
- this.execute();
- }
-
- execute() {
- this.cleanup();
- contextStack.push(this);
- try {
- this.effect();
- } finally {
- contextStack.pop();
- }
- }
-
- cleanup() {
- for (const dep of this.dependencies.values()) {
- dep.observers.delete(this);
- }
- this.dependencies.clear();
- }
- }
-
- export class Observable<T = unknown> {
- private value: T;
-
- observers: Set<Observer> = new Set();
-
- constructor(init: T) {
- this.value = init;
- }
-
- get() {
- const activeObserver = contextStack[contextStack.length - 1];
- if (activeObserver) {
- this.observers.add(activeObserver);
- activeObserver.dependencies.add(this);
- }
- return this.value;
- }
-
- set(next: T) {
- this.value = next;
- for (const observer of Array.from(this.observers.values())) {
- observer.execute();
- }
- }
- }
-
- export class Mapping<T extends unknown> {
- private observable: Observable<T>;
-
- private observer: Observer<T>;
-
- constructor(mapping: { (): T }) {
- this.observable = new Observable(undefined as T);
- this.observer = new Observer(() => {
- const result = mapping();
- this.observable.set(result);
- return result;
- });
- }
-
- get() {
- return this.observable.get();
- }
- }
|