【发布时间】:2019-05-24 20:29:40
【问题描述】:
我有一个函数应该从一个 api 中提取数据,然后使用结果从其他几个 api 中获取数据。第一次数据拉取对于所有这些都是必要的,但是一些后续调用可以并行运行,而其他调用则需要一个或多个并行调用返回的数据才能运行。目前,我通过在另一个订阅中进行三个订阅来完成其中的一些工作(对于那些正在计数的人来说,这是一个函数中的四个订阅),但这对我来说是错误的,我读过的所有内容都说它是要么是反模式,要么是完全错误的。我需要一种方法来让所有这些事情以正确的顺序运行——在需要顺序的地方——并返回我的数据。
我研究了几个 rxjs 选项,我认为我需要使用 forkJoin(对于可以并行运行的项目)和 mergeMap(对于依赖于 forkJoin 结果的项目)的某种组合。当前的设置是调用我的服务并订阅,然后在该订阅中 forkJoin 并调用其他几个函数,订阅该函数并在其中再执行两个调用并订阅其他调用。
getThingFromService(id: number): any {
const drinks = {};
this.thingService.getThingById(id)
.subscribe((thing) => {
this.thing = thing;
forkJoin([
this.getTea(thing.tea.id),
this.getCoffee(thing.coffee.id),
this.getSoda(thing.soda.id)
])
.subscribe((data) => {
drinks.tea = data[0];
drinks.coffee = data[1];
drinks.soda = data[2];
this.getCoffeeTypeById(drinks.coffee.bean.id)
.subscribe((bean) => {
drinks.coffeeBean = bean;
})
this.getSodaTypeById(drinks.soda.flavors.id)
.subscribe((flavor) => {
drinks.sodaFlavor = flavor;
});
});
)}
}
getTea(id: number) {
return this.thingService.getTea(id);
}
getCoffee(id: number) {
return this.thingService.getCoffee(id);
}
getSoda(id: number) {
return this.thingService.getSoda(id);
}
getCoffeeTypeById(id: number) {
return this.otherService.getCoffee(id);
}
getSodaTypeById(id: number) {
return this.yetAnotherService.getSoda(id);
}
关于这段代码的一切都让我感到困扰。首先,它读起来很混乱,而且不是很清楚。接下来,这是一个大大简化的版本。实际函数大约有 90 行。然后,它不会 100% 起作用。我认为 getSodaTypeById 正在解决其他所有问题,因此在我需要它时不可用,所以如果我记录它的结果是“未定义”。最后,必须有某种方法来完成我想做的所有事情,并且只需一个订阅即可。
有有效的坏代码、无效的坏代码和有效的坏代码。我无法决定哪一个是最糟糕的。
编辑:删除“记录”并替换为“事物”
【问题讨论】: