可观察的订阅未被调用

时间:2017-02-04 00:20:47

标签: angular typescript rxjs rxjs5

我有一个Observable,我将其用于将承诺转换为订阅。这导致我需要迭代一个集合来调用每个元素上的HTTP服务。我使用forkJoin等待所有这些调用完成,以便我可以做其他事情,但不幸的是,我的订阅没有被调用。你看到我在这里失踪了吗?

Observable.fromPromise(this.users.getElements()).subscribe(results => {
  Observable.forkJoin(
    results.map(
      aUser => this.HttpService.submitUser(aUser).subscribe(
        results => {
          this.progress += 1;
        },
        err => {
          this.progress += 1;
          this.handleError(<any>err);
        })
    ).subscribe(
      //it never gets to either of these calls after all service calls complete
      data => {
        debugger;
        console.log(data);
        this.reset();
      },
      err => {
        debugger;
        console.log(err);
        this.reset();
      }
    ));
});

2 个答案:

答案 0 :(得分:2)

有一点是你没有订阅传递给forkJoin()的每个Observable。操作员必须自己完成。

如果您希望在每个Observable完成时收到通知,您可以使用.do(undefined, undefined, () => {...})

let observables = [
  Observable.of(42).do(undefined, undefined, () => console.log('done')),
  Observable.of('a').delay(100).do(undefined, undefined, () => console.log('done')),
  Observable.of(true).do(undefined, undefined, () => console.log('done')),
];

Observable.forkJoin(observables)
  .subscribe(results => console.log(results));

打印到控制台:

done
done
done
[ 42, 'a', true ]

最终还有.finally()运营商。但是,它与使用.do()不同。

编辑:

当任何源Observable失败时,forkJoin()运算符重新发出错误(这意味着它也失败)。
这意味着您需要单独捕获每个源Observable中的错误(例如,使用catch()运算符)。

let observables = [
  Observable.throw(new Error())
    .catch(() => Observable.of('caught error 1'))
    .do(undefined, undefined, () => console.log('done 1')),

  Observable.of('a')
    .delay(100).catch(() => Observable.of('caught error 2'))
    .do(undefined, undefined, () => console.log('done 2')),

  Observable.of(true)
    .catch(() => Observable.of('caught error 3'))
    .do(undefined, undefined, () => console.log('done 3')),
];

Observable.forkJoin(observables)
  .subscribe(results => console.log(results));

打印哪些:

done 1
done 3
done 2
[ 'caught error 1', 'a', true ]

答案 1 :(得分:0)

我认为你不需要在地图上订阅。

Observable.fromPromise(this.users.getElements()).subscribe(results => {
  Observable.forkJoin(
    results.map(
      aUser => this.HttpService.submitUser(aUser))
    ).subscribe(
      //it never gets to either of these calls after all service calls complete
      data => {
        debugger;
        console.log(data);
        this.reset();
      },
      err => {
        debugger;
        console.log(err);
        this.reset();
      }
    ));
});

请注意,在这里的rxjs示例中:

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md

他们没有订阅个人的观察者 - ForkJoin让他们全部继续,然后等待所有人返回(在你的订阅中)。

编辑:

forkjoin源在这里:

https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/forkjoin.js

并且它看起来并不像每个完成时都找到钩子。我认为接近UI栏的最佳方法是让每个映射的observable单独订阅,所有调用函数来增加UI计数栏变量,并对“完整性”进行一些测试,允许您使用数据。