我正在使用Angular RxJs subscribe
进行HttpClient
调用,然后使用第一个中的值进行另一个调用。在这种情况下,有一个调用来获取address object
,然后我使用该对象进行了调用。像这样:
@Injectable()
export class AddressService {
constructor(private http: HttpClient) { }
getById(addressId: string, userId: string) {
return this.http.get(BACKEND_URL + 'getAddressById/' + [addressId, userId]);
}
}
export class AddressModalComponent implements OnInit {
constructor(private alertService: AlertService, private addressService: AddressService, @Inject(MAT_DIALOG_DATA) public data: any, private dropdownService: DropdownService)
ngOnInit() {
this.addressService.getById(this.data.id, this.data.userId)
.subscribe(
(address: Address) => {
this.dropdownService.getCidadesBrByEstado(address.name)
.subscribe((cities: BrCity[]) => {
this.cities = cities;
this.address = address;
},
error => console.log(error));
}, error => { this.alertService.error(error);
}
);
}
}
}
我正在尝试避免多个订阅,我的代码中有很多这样的订阅。我需要像Async/Await
这样的Node.js promises
方法,但是要在组件级别使用Observables。我对RxJs commands
不太熟悉...有没有更好的方法可以只用一个subscribe
和catch
拨打许多电话?
答案 0 :(得分:5)
尝试类似的东西:
import { map, switchMap } from 'rxjs/operators'
this.addressService.getById(this.data.id, this.data.userId).pipe(
switchMap(address => this.dropdownService.getCidadesBrByEstado(address.name).pipe(
// this pass both cities and address to the next observable in this chain
map(cities => ({ cities, address }))
))
).subscribe(({ cities, address }) => {
this.cities = cities
this.address = address
})
答案 1 :(得分:2)
假设您实际上并不关心流,您也可以在这种情况下将 Observables 转换为 promises 并使用 async/await
:
async ngOnInit(): Promise<void> {
this.address = await this.addressService.getById(this.data.id, this.data.userId).toPromise();
this.cities = await this.dropdownService.getCidadesBrByEstado(this.address.name).toPromise();
}
并确保您也发现了错误。 try catch
例如。
答案 2 :(得分:1)
对于使用RxJS时的角度,建议使用Observable类。要解决RxJS中的回调地狱,可以使用Observable的Operators api(例如switchMap()方法)(针对不同场景的更多方法是map(),concatMap()等)。这是我有关使用switchMap()方法的示例:
(1)我遇到的情况:我想订购serviceC,但是serviceC需要订购serviceB,而serviceB需要订购serviceA
const serviceA(params): Observable<any>;
const serviceB(params): Observable<any>;
const serviceC(params): Observable<any>;
serviceA(paramsA).subscribe(
serviceAResult => {
serviceB(paramsB).subscribe(
serviceBResult => {
serviceC(params).subscribe(
serviceCResult => {
// here is my logic code. Oh, Shit subscribe hell!
}
)
}
)
}
)
(2)使用switchMap()方法优化代码结构
const serviceB$ = serviceA(paramsA).pipe(
switchMap(serviceAResult => {
return serviceB(paramsB);
})
);
const serviceC$ = serviceB$.pipe(
switchMap(serviceBResult => {
return serviceC(paramsC);
})
);
serviceC$.subscribe(
serviceCResult => {
// here is my logic code.
},
error =>{
// handle error
}
);
关于处理callback hell的好帖子。