【问题标题】:Angular 2 : Chain Observables in ResolverAngular 2:解析器中的链 Observables
【发布时间】:2017-03-07 11:28:43
【问题描述】:

我是 Angular2 和 observables 的新手。我试图将一系列可观察的结果返回给我的解析器,但在 SO 上找不到答案。当我只返回一个可观察对象时一切正常,但当它们被链接时会失败。我已将代码简化为连续两次调用相同的测试函数:

@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();
             });
        }
}

组件:

export class SwComponent implements OnInit {constructor(
    private route: ActivatedRoute,
    private router: Router
  ) { }

  ngOnInit(): void {
    this.route.data.forEach((data: any) => {
      // Handle data received
     });
  }
};

软件服务:

  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,...)。主要原因是因为我只是没有得到它们的功能方面。我鼓励同一条船上的人看看查尔斯·斯卡尔法尼的these excellent series of articles on functional programming

【问题讨论】:

    标签: angular typescript observable resolver


    【解决方案1】:

    resolve 函数期望返回一个 observable。你所做的不正确,因为你只返回一个异步结果。您正在调用第一个可观察对象,然后订阅该可观察对象。所以时间过去了,只有当第一个 observable 被解决时,你才返回一个 observable。

    对于这样的东西(与 Promise.then 具有相似的行为),您应该使用 flatMap/mergeMap(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();
                 );
            }
    }
    

    这会立即返回一个 observable。

    mergeMap 所做的是获取一个事件作为输入(在本例中是您的第一次 getTestData() 调用的结果)并期望您返回另一个 observable。在引擎盖下,它将订阅这个 observable 并将结果展平。

    mergeMap 上有很多文章,如果不清楚,我建议您阅读一些。这是一个好的开始:https://github.com/btroncone/learn-rxjs/blob/master/operators/transformation/mergemap.md

    【讨论】:

    • @KwibtenP 谢谢,出于某种原因,我认为 mergeMap 和 flatMap 是 http 调用所独有的。代码现在返回另一个错误:TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
    • 你能把你有atm的代码贴出来吗?我看到我在mergeMap 的回答中错过了一个return 语句。我更新了它(见上面的答案)。如果有帮助,你可以试试。
    • 感谢 KwintenP,它适用于更新版本!
    猜你喜欢
    • 2017-05-25
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多