我有一個 Launch 方法,它接受一些引數并啟動一個引擎。當引擎啟動時,它回傳實體名稱。使用此實體名稱,我想定期查詢另一個服務,每隔 2 秒就知道狀態是否更改為“成功”或“失敗”我在第一個訂閱中做了一個 do while 回圈,但它沒有按預期作業。
instanceStatus: string = "Initialized";
instanceName:string = "InstanceName";
Launch(sessionId: string, projectName: string, f: string[]) {
this.service.Launch(sessionId, projectName, this.f)
.pipe(first())
.subscribe(
instanceName => {
localStorage.setItem('instanceName', instanceName);
this.instanceName = instanceName;
setTimeout(() => {
do {
this.service.getEngineStatus(this.instanceName)
.pipe(first())
.subscribe(
status => {
this.instanceStatus = status;
console.log(status);
console.log(this.instanceStatus);
this.loadingService.showSpinner({ text: 'Modeling is running...' });
if (this.instanceStatus === "Succeeded") {
this.messageService.add({ severity: Severity.Success, summary: 'Fault modeling completed', detail: 'Via MessageService' });
this.messageService.clear();
}
}
);
} while (this.instanceStatus !== "Succeeded")
}, 2000);
}
);
}
getEngineStatus(instanceName:string): Observable<string> {
this.serviceUrl = URL `?instance=` instanceName;
return this._http.get<string>(this.serviceUrl);
}
uj5u.com熱心網友回復:
你看過interval創建運算子嗎?我相信這可能是您需要使用的。我使用這個運算子試了一下,代碼如下所示:
Launch(sessionId: string, projectName: string, f: string[]) {
this.service
.Launch(sessionId, projectName, this.f)
.pipe(
first(),
tap((instanceName) => {
localStorage.setItem('instanceName', instanceName);
this.instanceName = instanceName;
}),
switchMap(() => interval(2000)),
takeWhile(() => !['Succeeded', 'Failed'].contains(this.instanceStatus)),
tap(() => {
this.loadingService.showSpinner({
text: 'Modeling is running...',
});
}),
switchMap(() => this.service.getEngineStatus(this.instanceName))
)
.subscribe((status) => {
this.instanceStatus = status;
this.loadingService.hideSpinner();
console.log(status);
console.log(this.instanceStatus);
if (this.instanceStatus === 'Succeeded') {
this.messageService.add({
severity: Severity.Success,
summary: 'Fault modeling completed',
detail: 'Via MessageService',
});
this.messageService.clear();
}
});
}
uj5u.com熱心網友回復:
避免嵌套訂閱。而是嘗試使用更高階的映射運算子,例如
switchMap.使用 RxJS 函式(如或 )進行輪詢,而不是使用
for或 之類的 JS 陳述句。whileintervaltimer使用
do運算子來做一些副作用,比如將資料推送到本地存盤。
import { Observable, timer } from 'rxjs';
import { do, finalize, switchMap, takeWhile } from 'rxjs/operators';
POLL_INTERVAL = 2000;
instanceStatus: string = "Initialized";
instanceName:string = "InstanceName";
this.Launch(sample, sample, sample).pipe(
switchMap((instanceName: any) =>
timer(0, POLL_INTERVAL).pipe( // <-- start immediately and poll every 'n' secs
switchMap(() => this.service.getEngineStatus(instanceName)),
takeWhile((instanceStatus: any) => instanceStatus === 'Succeeded'), // <-- stop poll when status !== 'Succeeded'
finalize(() => { // <-- run when polling stops
this.messageService.add({
severity: Severity.Success,
summary: 'Fault modeling completed',
detail: 'Via MessageService'
});
this.messageService.clear();
})
).subscribe({
next: (instanceStatus: any) => this.instanceStatus = instanceStatus
});
)
)
Launch(sessionId: string, projectName: string, f: string[]): Observable<any> {
return this.service.Launch(sessionId, projectName, this.f).pipe(
first(),
do((instanceName: any) => {
localStorage.setItem('instanceName', instanceName);
this.instanceName = instanceName;
})
);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/352692.html
下一篇:在同一個函式中等待訂閱
