![](/img/trans.png)
[英]angular2. how can I make a route append queryParam with exists params?
[英]Angular2. How can I check if an observable is completed?
在我的頁面中有一個生成報告的按鈕。 該報告需要在頁面加載時使用對 rest 端點的 http 調用加載的數據,但我不能保證當用戶按下報告按鈕時它們會被加載。
我如何觀察可觀察對象是否已完成,如果未完成,則等待操作直到 http 調用完成? 這是一些代碼:
loadCompanies(): void {
this._companyService.getCompanies().subscribe(
response => {
this.companiesModel = response;
},
err => console.log(err)
);
}
generateReport() {
// check if observable that loads companies is completed and do the
// action using companiesModel.
}
一種選擇是在加載公司中設置標志,其值為“正在加載”和“已完成”,並在generateReport()
中等待直到標志完成,但如果可能,我更喜歡使用Observable
API 的解決方案。
您可以通過在subscription
中使用onCompleted
回調來做到這一點。 例如,假設您在用戶按下報告按鈕時顯示加載欄;
loadCompanies(): void {
this._companyService.getCompanies().subscribe(
response => {
this.companiesModel = response;
},
err => {
console.log(err);
//closeLoadingBar();
},
() => {
//do whatever you want
//closeLoadingBar()
}
)
}
generateReport() {
//showLoadingBar()
this.loadCompanies();
}
如果您從 http 調用中收到錯誤,則不會調用onCompleted
方法,只會調用onError
。 如果成功,將在您的onNext
方法之后調用onCompleted
方法。
這是subscribe的文檔。 我希望它有所幫助!
另一種解決方案:
實際上 subscribe 函數需要三個參數:
onNext onError onCompleted
this._companyService.getCompanies().subscribe(
(response) => { this.companiesModel = response; },
(err) => { console.log(err) },
(finally) => { console.log('finally') }
);
方法
finally()
在源可觀察序列正常或異常終止后調用指定的操作。
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/finally.md
在這種情況下,使用concatMap運算符來保證僅在前一個操作完成后才執行下一個操作非常有用。
loadCompanies(): void {
this._companyService.getCompanies()
.concatMap(companyList => this.getObservableGenerateReport(companyList))
.subscribe(
response => {
this.companiesModel = response;
},
err => console.log(err)
);
}
//Create observable to generate the report
getObservableGenerateReport(response: any): Observable<myReportList> {
return Observable.create(observer => {
if (generateReport().isSuccessful) {
observer.next(myReportList);
observer.complete();
} else {
console.log(err, 'Ups, something was wrong!');
observer.next({});
observer.complete();
}
});
}
如果您這樣做是為了調試,最簡單的解決方案是使用tap
的complete
參數:
tap(next: null, error: null, complete: () => void)
使用源source$
它看起來像這樣:
source$.pipe(
tap(undefined, undefined, console.log)
);
我想出的解決方案是使用共享的可觀察對象,將請求保存為熱可觀察對象,這樣當單擊報告按鈕時它將等待請求或在請求完成時立即生成。
public companiesModel: Company[];
/** pending request, hot Observable (will emit immediately if complete) */
private companiesRequest: Observable<Company[]>;
constructor(
private _companyService: CompanyService
) {}
public ngOnInit(): void {
this.loadCompanies();
}
public generateReport(): void {
if (this.companiesRequest) {
// will not make an other network request
this.companiesRequest.subscribe(
response => {
// action using companiesModel.
},
err => console.log(err)
);
}
}
private loadCompanies(): void {
this.companiesRequest = this._companyService.getCompanies().pipe(shareReplay());
this.companiesRequest.subscribe(
response => {
this.companiesModel = response;
},
err => console.log(err)
);
}
https://stackblitz.com/edit/check-if-an-observable-is-completed?file=src%2Fapp%2Fapp.component.ts
更新:您可以更進一步,使 UI 異步https://stackblitz.com/edit/check-if-an-observable-is-completed-async-ui?file=src%2Fapp%2Fapp.component。網頁格式
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.