我有一个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();
}
));
});
答案 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计数栏变量,并对“完整性”进行一些测试,允许您使用数据。