У меня есть функция, которая должна извлекать данные из одного 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 разрешается после всего остального и поэтому недоступен, когда мне это нужно, поэтому в результате я регистрирую его как «undefined». Наконец, должен быть какой-то способ сделать все, что я хочу сделать, это ясно и с одной подпиской.
Существует плохой код, который работает, плохой код, который не работает, и плохой код, который работает. Я не могу решить, какой из них является худшим.
Редактировать: удалить «запись» и заменить на «вещь»