Использование rx js для регулирования обратного вызова - PullRequest
3 голосов
/ 26 мая 2020

Я использую API, в котором я регистрирую часто повторяющийся обратный вызов.

function myCallback(event) {
  // do things with event, something computationally intensive
}

const something = createSomething({
  onSomethingHappened: myCallback
})

Я хотел бы ограничить скорость, с которой этот обратный вызов запускается, возможно, используя дроссель . В этом проекте используется Angular, который связывает rx. Как я могу адаптировать свой код, чтобы myCallback он дросселировался на 300 мс с помощью rx?

У меня есть базовая c gr asp о том, как работают наблюдаемые, но было немного запутано, чтобы выяснить, как обратный вызов интерфейс будет преобразован в наблюдаемый интерфейс.

(редактируется по мере поступления ответов)

Ответы [ 4 ]

2 голосов
/ 27 мая 2020

Я думаю, вы можете использовать fromEventPattern:

let something;

const src$ = fromEventPattern(
  handler => (something = createSomething({ onSomethingHappened: handler })),
);

src$.pipe(
  throttleTime(300),
  map(args => myCallback(args))
);

Примечание: предполагается, что myCallback является синхронной операцией.

Первый аргумент, переданный в fromEventPattern, - это addHandler. Он также может иметь removeHandler, куда вы можете поместить свой лог разборки c (например: освобождение из памяти, обнуление значений и т. Д. c).


Чтобы получить лучшее понимание того, что такое handler и почему он там используется, давайте посмотрим, как реализован fromEventPattern:

return new Observable<T | T[]>(subscriber => {
  const handler = (...e: T[]) => subscriber.next(e.length === 1 ? e[0] : e);

  let retValue: any;
  try {
    retValue = addHandler(handler);
  } catch (err) {
    subscriber.error(err);
    return undefined;
  }

  if (!isFunction(removeHandler)) {
    return undefined;
  }

  // This returned function will be called when the observable
  // is unsubscribed. That is, on manual unsubscription, on complete, or on error.
  return () => removeHandler(handler, retValue) ;
});

Source .

Как видите , через handler, вы можете позволить возвращаемому наблюдаемому, когда пришло время что-то испустить.

1 голос
/ 26 мая 2020

Я не очень хорошо знаком с Rx JS, но возможно следующее.

Проверьте это на StackBlitz: https://stackblitz.com/edit/rxjs-ijzehs.

import { Subject, interval } from 'rxjs';
import { throttle } from 'rxjs/operators';

function myCallback(v) {
  // do things with event, something computationally intensive
  console.log("got value", v)
}

const o$ = new Subject()

o$.pipe(throttle(v => interval(300))).subscribe(myCallback)

const something = createSomething({
  onSomethingHappened: v => {
    o$.next(v)
  }
})

function createSomething({ onSomethingHappened }) {
  let i = 0
  setInterval(() => {
    console.log("calling onSomethingHappened")
    onSomethingHappened(i++)
  }, 100)
}
1 голос
/ 26 мая 2020

Вы можете просто передать оператор throttleTime потоку fromEvent.

import { fromEvent } from 'rxjs';
import { throttleTime } from 'rxjs/operators';

const mouseMove$ = fromEvent(document, 'mousemove');
mouseMove$.pipe(throttleTime(300)).subscribe(...callback);
0 голосов
/ 27 мая 2020

Вы можете использовать простой Subject

function myCallback(event) {
  // do things with event, something computationally intensive
}

// subject presents all emits.
const subject = new Subject();
const subscription = subject.pipe( 
  throttle(300), // now we limit it as you wanted.
).subscribe(myCallback);

const something = createSomething({
  onSomethingHappened: e => subject.next(e), // using subject instead of callback.
})

// subscription.unsubscribe(); // once we don't need it.
...