问题描述
我是Angular2和Observable的新手.我正在尝试将一连串可观察的结果返回给我的解析器,但找不到关于SO的答案.当我只返回一个可观察到的东西时,一切工作正常,但是当它们链接在一起时,一切都失败了.我将代码简化为连续两次调用相同的测试函数:
I am new to Angular2 and observables. I am trying to return the result of a chain of observables to my resolver and couldn't find an answer on SO. Everything works fine when I return only one observable, but fails when those are chained. I've simplified the code to calling consecutively twice the same test function :
@Injectable()
export class SwResolve implements Resolve<any> {
constructor(private swService: SwService) {}
resolve (route: ActivatedRouteSnapshot): Observable<MyObject> | Promise<any> | any {
this.swService.getTestData().subscribe(data => {
return this.swService.getTestData();
});
}
}
SwComponent:
SwComponent :
export class SwComponent implements OnInit {constructor(
private route: ActivatedRoute,
private router: Router
) { }
ngOnInit(): void {
this.route.data.forEach((data: any) => {
// Handle data received
});
}
};
SwService:
SwService :
getTestData() {
return Observable.create(observer => {
let testObject : SwDataObject = {
'labels':['value0','value1'],
'desktop':[123,456],
'mobile':[789,1011]
};
observer.next(testObject);
observer.complete();
});
}
我在这里做什么错了?
谢谢!
编辑6月17日:添加更多信息,这花了我一段时间来围绕RxJs的方法(flatMap,mergeMap等).主要原因是因为我只是不了解它们的功能方面.我鼓励同一条船上的人们看看查尔斯·斯卡法尼(Charles Scalfani)撰写的有关函数式编程的这些优秀文章系列.
Edit Jun 17:Adding some more info, as it took me a while to wrap my head around RxJs' methods (flatMap, mergeMap, ...). The main reason was because I just didn't get the functional aspect of them. I encourage people in the same boat to have a look at these excellent series of articles on functional programming by Charles Scalfani.
推荐答案
resolve函数期望返回一个可观察的对象.您所做的操作不正确,因为您仅返回了异步结果.您正在调用第一个可观察对象,然后订阅该可观察对象.因此,时间流逝,只有第一个可观察的问题得到解决,您才能返回一个可观察的问题.
The resolve function expects an observable to be returned. What you are doing isn't correct since you are only returning an async result. You are calling the first observable and then subscribe to that observable. So time passes and only if the first observable is resolved, you are returning an observable.
您应该使用诸如flatMap/mergeMap(在RxJS5中为别名)这样的东西(与Promise.then(类似)具有类似的行为).
What you should be using for stuff like this (which has similar behaviour to Promise.then (kind of)) is a flatMap/mergeMap (aliases in RxJS5).
将代码重构为此:
@Injectable()
export class SwResolve implements Resolve<any> {
constructor(private swService: SwService) {}
resolve (route: ActivatedRouteSnapshot): Observable<MyObject> | Promise<any> | any {
return this.swService.getTestData().mergeMap(data =>
return this.swService.getTestData();
);
}
}
这将立即返回一个可观察值.
What this will do is return an observable immediately.
mergeMap所做的是获取一个事件作为输入(在这种情况下,这是您第一次getTestData()调用的结果),并希望您返回另一个可观察的对象.在引擎盖下,它将订阅此可观察结果并展平结果.
What mergeMap does is get an event as input (in this case the result from your first getTestData()-call) and expect you to return another observable. Under the hood it will subscribe to this observable and flatten the result.
关于mergeMap的文章很多,因此,如果不清楚,我建议您阅读一些.这是一个好的开始: https://github.com/btroncone/learn-rxjs/blob/master/operators/transformation/mergemap.md
There are a ton of articles on mergeMap so if this is unclear, I suggest you read a few. Here's a good start: https://github.com/btroncone/learn-rxjs/blob/master/operators/transformation/mergemap.md
这篇关于Angular 2:解析器中的链可观察项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!