![](/img/trans.png)
[英]How to add extra fields in RxJS observable and wait for it to complete?
[英]how to wait http response in observable (rxjs)
這是原始代碼。
// info.service.ts.
this.info$ = new BehaviorSubject<Info>(null);
async getInfo() {
try {
const info = await this.infoApi.getInfo();
console.log(info) // info {name: 'sdf', 'age': 12}
this.info$.next(info);
} catch {
this.info$.next(null);
}
}
// infoApi Class
getInfo() {
return this.apiService.get<Info>(`/info`, this.infoService....);
}
對於使用 rxjs 進行異步處理,我們修改代碼如下。 我項目中的其他異步處理代碼也通過如下方式修改為rxjs,運行正常。 但是,只有 getinfo 服務不能正常工作。 異步處理未正常進行。 作為檢查網絡面板的結果,信息數據請求在管理狀態下被檢查。 如果有任何預期的問題,請告訴我。
(異步,等待不可用,所以我正在嘗試使用 Rxjs。)
兩個版本的代碼都沒有按預期工作。
第一個版本
// info.service.ts
getInfo() {
from(this.infoApi.getInfo()).subscribe(
info => {this.info$.next(info);
console.log(info) // null
error => {this.info$.next(error)
}
)
}
// infoApi Class
getInfo() {
return this.apiService.get<Info>(`/info`, this.infoService....);
}
// api.service.ts
get<T>(url: string, opts?: options) {
return this.request<T>('GET', url, null, opts);
}
第二版
// info.service.ts
getInfo() {
this.infoApi.getInfo().subscribe(
info => {this.info$.next(info);
console.log(info) // null
error => {this.info$.next(error)
}
)
}
// infoApi Class
getInfo() {
return from(this.apiService.get<Info>(`/info`, this.infoService....);
}
// api.service.ts
get<T>(url: string, opts?: options) {
return this.request<T>('GET', url, null, opts);
}
getInfo() 返回一個 Observable,不需要在 info.servive.ts 中使用 from()。
訂閱部分中的格式也可以是:
getInfo() {
this.infoApi.getInfo()
.subscribe({
next: (info => {this.info$.next(info);
console.log(info)}), // null
error: (error => this.info$.next(error))
}
)
}
我使用 randomAPI 構建了一個小例子
信息服務.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
// Using random data api for example
export type Info = {
blend_name: string;
};
@Injectable({
providedIn: 'root',
})
export class infoApiService {
info$: BehaviorSubject<Info> = new BehaviorSubject<Info>(null);
constructor(private http: HttpClient) {
// Use subscription for making BehaviorSubject work...
this.getInfo().subscribe()
}
getInfo() {
return this.http
.get<Info>('https://random-data-api.com/api/coffee/random_coffee')
.pipe(
tap({
next: (info) => {
this.info$.next(info);
console.log('logging in tap', info);
},
error: (error) => this.info$.error(error),
})
);
}
}
app.component.ts
import { Component, OnInit, VERSION } from '@angular/core';
import { Observable } from 'rxjs';
import { Info, infoApiService } from './info.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
infoObs$!: Observable<Info>;
constructor(private info: infoApiService) {
this.infoObs$ = this.info.info$.asObservable();
}
}
app.component.html
<div *ngIf="infoObs$ | async">
<h3>The info is here : {{ (infoObs$ | async).blend_name }}</h3>
</div>
它在 StackBlitz 中可用: https ://stackblitz.com/edit/angular-ivy-wgjsfa?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts,src%2Fapp%2Finfo.service .ts
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.