[英]RxJS throttle behavior; get first value immediately
示例 Plunkr: https ://plnkr.co/edit/NZwb3ol8CbZFtSc6Q9zm ? p = preview
我知道 RxJS (5.0 beta.4) 有這 3 種節流方法:
auditTime()
、 throttleTime()
和auditTime()
debounceTime()
我正在尋找的行為是lodash
默認情況下在throttle
上所做的:
理論上這應該是這樣的:
inputObservable
.do(() => cancelPreviousRequest())
.throttleTime(500)
.subscribe((value) => doNextRequest(value))
但是
throttleTime
從來沒有給我的最后一個值,如果發射節氣門超時debounceTime
不會立即觸發auditTime
不會立即觸發我可以結合任何 RxJS 方法來實現所描述的行為嗎?
對於在 2018 年之后尋找此內容的任何人:這是一年多前添加的內容,但由於某種原因,文檔尚未更新。
您可以簡單地將一個配置對象傳遞給throttleTime
。 默認值為{ leading: true, trailing: false }
。 要實現此處討論的行為,您只需將trailing
設置為true
: { leading: true, trailing: true }
編輯:
為了完整起見,這是一個工作片段:
import { asyncScheduler } from 'rxjs'
import { throttleTime } from 'rxjs/operators'
...
observable.pipe(
throttleTime(100, asyncScheduler, { leading: true, trailing: true })
)
對於較舊的 RxJ,我編寫了一個concatLatest
運算符,可以完成您想要的大部分操作。 有了它,您可以使用以下代碼獲得節流行為:
const delay = Rx.Observable.empty().delay(500);
inputObservable
.map(value => Rx.Observable.of(value).concat(delay))
.concatLatest()
.subscribe(...);
這是操作員。 我嘗試更新它以使用 RxJS5:
Rx.Observable.prototype.concatLatest = function () {
/// <summary>
/// Concatenates an observable sequence of observable sequences, skipping sequences that arrive while the current sequence is being observed.
/// If N new observables arrive while the current observable is being observed, the first N-1 new observables will be thrown
/// away and only the Nth will be observed.
/// </summary>
/// <returns type="Rx.Observable"></returns>
var source = this;
return Rx.Observable.create(function (observer) {
var latest,
isStopped,
isBusy,
outerSubscription,
innerSubscription,
subscriptions = new Rx.Subscription(function () {
if (outerSubscription) {
outerSubscription.unsubscribe();
}
if (innerSubscription) {
innerSubscription.unsubscribe();
}
}),
onError = observer.error.bind(observer),
onNext = observer.next.bind(observer),
innerOnComplete = function () {
var inner = latest;
if (inner) {
latest = undefined;
if (innerSubscription) {
innerSubscription.unsubscribe();
}
innerSubscription = inner.subscribe(onNext, onError, innerOnComplete);
}
else {
isBusy = false;
if (isStopped) {
observer.complete();
}
}
};
outerSubscription = source.subscribe(function (newInner) {
if (isBusy) {
latest = newInner;
}
else {
isBusy = true;
if (innerSubscription) {
innerSubscription.unsubscribe();
}
innerSubscription = newInner.subscribe(onNext, onError, innerOnComplete);
}
}, onError, function () {
isStopped = true;
if (!isBusy) {
observer.complete();
}
});
return subscriptions;
});
};
這是一個更新的 plunkr: https ://plnkr.co/edit/DSVmSPRijJwj9msefjRi ? p = preview
注意我將您的 lodash 版本更新為最新版本。 在 lodash 4.7 中,我重寫了油門/去抖操作符來修復一些邊緣情況的錯誤。 您使用的 4.6.1 仍然存在一些錯誤,但我認為它們不會影響您的測試。
我使用了 auditTime 運算符並更改了 2 行以實現所需的行為。
新 plunker: https ://plnkr.co/edit/4NkXsOeJOSrLUP9WEtp0 ? p = preview
原文:
變化:
來自(審計時間):
protected _next(value: T): void {
this.value = value;
this.hasValue = true;
if (!this.throttled) {
this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, this));
}
}
clearThrottle(): void {
const { value, hasValue, throttled } = this;
if (throttled) {
this.remove(throttled);
this.throttled = null;
throttled.unsubscribe();
}
if (hasValue) {
this.value = null;
this.hasValue = false;
this.destination.next(value);
}
}
到(審計時間立即):
protected _next(value: T): void {
this.value = value;
this.hasValue = true;
if (!this.throttled) {
// change 1:
this.clearThrottle();
}
}
clearThrottle(): void {
const { value, hasValue, throttled } = this;
if (throttled) {
this.remove(throttled);
this.throttled = null;
throttled.unsubscribe();
}
if (hasValue) {
this.value = null;
this.hasValue = false;
this.destination.next(value);
// change 2:
this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, this));
}
}
所以我next
值之后開始超時。
用法:
inputObservable
.do(() => cancelPreviousRequest())
.auditTimeImmediate(500)
.subscribe((value) => doNextRequest(value))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.