簡體   English   中英

使用 rxjs 限制回調

[英]Using rxjs to throttle a callback

我正在使用一個 API,我在其中注冊了一個經常發生的回調。

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

const something = createSomething({
  onSomethingHappened: myCallback
})

我想限制此回調觸發的速率,可能使用throttle 該項目使用捆綁 rx 的 Angular。 如何調整我的代碼,以便使用 rx 將myCallback限制在 300 毫秒?

我對 observables 的工作原理有基本的了解,但是弄清楚回調接口如何轉換為 observable 接口有點令人困惑。

(隨着答案的出現而編輯)

我認為您可以使用fromEventPattern

let something;

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

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

注意:這假設myCallback是一個同步操作。

傳遞給fromEventPattern的第一個參數是addHandler 它也可以有removeHandler ,您可以在其中放置您的拆卸邏輯(例如:從 memory 釋放,清空值等)。


為了更好地理解什么是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) ;
});

來源

正如你所看到的,通過handler ,你可以讓返回的 observable 在發出某些東西的時候。

您可以將操作員throttleTime時間 pipe 設置為fromEvent stream。

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

const mouseMove$ = fromEvent(document, 'mousemove');
mouseMove$.pipe(throttleTime(300)).subscribe(...callback);

我對 RxJS 不是很熟悉,但可能會出現以下情況。

在 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)
}

您可以使用簡單的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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM