[英]How to stop subscription by using multiple conditions with takeUntil
import { timer } from 'rxjs/internal/observable/timer';
)或者
它只是根據時間停止執行(使用import { timer } from 'rxjs/internal/observable/timer';
)
出於示例目的,屬性、變量及其值的名稱已更改:
import { finalize } from 'rxjs/internal/operators/finalize';
import { interval } from 'rxjs/internal/observable/interval';
import { timer } from 'rxjs/internal/observable/timer';
import { takeUntil, first } from 'rxjs/operators';
import { merge, EMPTY, of } from 'rxjs';
.
. // Attributes and Class declaration here
.
async startProcess(): Promise<void> {
this.isProcessLoading = true;
const { someId } = await this.exampleService.execute().toPromise();
const interval$ = interval(1000);
const timeLimiter$ = timer(10000);
const request$ = this.exampleService.doRequest();
const isEventFinished$ = EMPTY;
// My goal here is for the result of this function to return an observable that notifies
// if the first parameter emits an event OR if the second parameter emits another. That is, I want to notify if any condition is valid
const stopConditions$ = merge(isEventFinished$, timeLimiter$);
const handleSuccess = (object: MyType) => {
if (object.status === 'FINALIZED') {
this.object = object;
isEventFinished$.subscribe();
}
};
const handleError = () => this.showErrorComponent = true;
interval$
.pipe(takeUntil(stopConditions$))
.pipe(finalize(() => this.isSimulationLoading = false))
.subscribe(() => request$.subscribe(handleSuccess, handleError));
}
代碼“有效”是因為timeLimiter$
在 10 秒后觸發takeUntil
。 但是,我希望有可能在時間限制之前停止......
我希望 takeUntil 也能夠從這里運行:
isEventFinished$.subscribe()
如果上面的代碼片段正確執行,它應該停止間隔 $,但它沒有。 那是我的問題
我不知道兩個管道是否比只使用一個這樣的管道有什么不同: .pipe(takeUntil(stopConditions$), finalize(() => this.isSimulationLoading = false))
。 但是,我已經嘗試過了,但沒有奏效
已經嘗試將此isEventFinished$
替換為: const isEventFinished$ = of(1)
和他的訂閱: timeLimiter$.pipe(first()).subscribe()
。 但這也不起作用。 實際上,這會阻止請求被執行(我不知道為什么)
我剛剛用 Stackblitz 嘗試了這段代碼,它“工作”了……但我不確定你到底想做什么? 然后我做了一些更新,以更好地了解發生了什么。
在此處查看 Stackblitz: https://stackblitz.com/edit/angular-takeuntil-deborahk
關鍵變化:
const stopConditions$ = merge(this.isEventFinished$, timeLimiter$).pipe(
tap(s => console.log("stop", s))
);
interval$.pipe(takeUntil(stopConditions$)).subscribe({
next: handleSuccess,
error: handleError,
complete: () => {
this.isSimulationLoading = false;
console.log("isSimulationLoading", this.isSimulationLoading)
}
});
這有幫助嗎?
編輯:我添加了一個“完成”按鈕來模擬任何會導致完成操作的操作。
通過將 isEventFinished 聲明為 Subject 或 BehaviorSubject 將isEventFinished
定義為 Observable(BehaviorSubject 有默認值,Subject 沒有)。
isEventFinished$ = new Subject<boolean>();
然后,每當完成事件發生時,使用next
方法將一個值發送到isEventFinished
stream 中。
this.isEventFinished$.next(true);
那么這段代碼應該可以工作:
const stopConditions$ = merge(this.isEventFinished$, timeLimiter$).pipe(
tap(s => console.log("stop", s))
);
interval$.pipe(takeUntil(stopConditions$)).subscribe({
next: handleSuccess,
error: handleError,
complete: () => {
this.isSimulationLoading = false;
console.log("isSimulationLoading", this.isSimulationLoading);
}
});
查看更新的閃電戰。
那樣有用嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.