使用Angular下的rxjs中的combineLatest()来保留多个Observable <T>的类型?

Kon*_*ten 4 rxjs typescript angular combinelatest

当我的组件加载时,我需要使用两个服务。两者都需要先完成,然后才能继续。这些步骤的完成顺序是随机的,不应顺序组成。设置遵循以下模式。

const observables = [
  this.donkeyService.getDonkey(),
  this.monkeyService.getMonkey()
];

combineLatest(observables)
  .subscribe(([donkeyResult, monkeyResult]) => {
    if (!!donkeyResult && !!monkeyResult) {
      ...
    }
  }
Run Code Online (Sandbox Code Playgroud)

我们注意到结果没有按预期输入。我们花了一段时间才意识到它,但是donkeyResult的类型不是Donkey,尽管下面定义了服务器!

getDonkey() : Observable<Donkey> { ... }
Run Code Online (Sandbox Code Playgroud)

最终,我意识到,当元素传递到接收数组时,它们会失去类型,因为数组本身是any []。因此,我们按以下方式使用投射进行管理。

const observables = [
  this.donkeyService.getDonkey(),
  this.monkeyService.getMonkey()
];

combineLatest(observables)
  .subscribe(([_1, _2]) => {
    const donkeyResult = _1 as Donkey;
    const monkeyResult = _2 as Monkey;

    if (!!donkeyResult && !!monkeyResult) {
      ...
    }
  }
Run Code Online (Sandbox Code Playgroud)

我想重构代码,以便数组将保留服务方法签名指定的类型,并且不会合并为any的公分母。

是否可以使TypeScript和/或Rxjs具有一个数组,其中第一个元素是,第二个元素是Monkey?我可以使用与数组不同的数据结构吗?

我尝试了(当然失败了)很多不同的方法,包括像这样通过直接在数组中强制转换类型来四处寻找。

...
.subscribe(([_1 as Donkey, _2 as Monkey]) => { ... }
Run Code Online (Sandbox Code Playgroud)

有保持整洁的整洁方法吗?由于我们拥有软件的这一部分,因此我们愿意一起更改所有方法,并有一些额外的时间来处理代码。

小智 5

首先,您必须输入函数和HTTP调用。

getMonkey(): Observable<Donkey> {
  return this.http.get<Donkey>(url);
}
Run Code Online (Sandbox Code Playgroud)

完成后,您必须输入可观察对象数组:

const observables: [Monkey, Donkey] = [
  this.getMonkey(),
  this.getDonkey(),
];
Run Code Online (Sandbox Code Playgroud)

最后,尽管不是必需的,您可以键入您的回调参数:

forkJoin(observables).subscribe(([monkey, donkey]: [Monkey, Donkey]) => {...});
Run Code Online (Sandbox Code Playgroud)