【问题标题】:How to avoid subscribe soup?如何避免订阅汤?
【发布时间】:2016-11-13 16:16:01
【问题描述】:

我有一个经常出现的模式,但我不知道解决它的最佳方法是什么。

我订阅了一个 observable(这里是路由器),它为我提供了值。我需要其中一个值来构建另一个请求以获取另一个 observable。但是我在订阅中有一个 observable。

我知道这不是一个好的模式,但我不知道该怎么做。

如果我使用第二个 observable 来获取另一个值并在 observable 的 observable 中获取另一个 observable。

如何解决这个问题,避免喝汤?

这是我的代码:

deal.component.ts

import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core';
import {Observable} from "rxjs/Observable";
import {ActivatedRoute} from "@angular/router";
import {DealsService} from "../deals.service";

@Component({
  templateUrl: './+deal.component.html',
  styleUrls: ['./+deal.component.scss']
})
export class DealRouterComponent implements OnInit {

  deal$: Observable<any>;
  public dealId:string;
  private sub:any;

  constructor(
    private route: ActivatedRoute,
    private dealsService: DealsService) {}

  ngOnInit() {
    this.sub = this.route.params
      .subscribe(params => {
        this.dealId = params['id'];
        this.deal$ = this.dealsService.getDeal(this.dealId);
      })
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}

deal.service.ts

import {Injectable, Inject} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {AngularFireDatabase} from "angularfire2";

@Injectable()
export class DealsService {

  constructor(private db: AngularFireDatabase) {}

  getDeal(id) {
    return this.db.object('deals/' + id);
  }

 }

deal.component.html

{{deal | async | json}}

【问题讨论】:

  • 这种模式类似于嵌套的“承诺地狱”。解决方案是使用 mergeMap (flatMap) 操作符链接 observables。

标签: angular rxjs reactive-programming observable


【解决方案1】:

Observable 可以通过operators 链接。这是 observable 的优势之一,我发现 this tutorial 是解释如何使用 ReactiveX 的最佳方法之一。

你不应该像 deal$ 那样改变 observable。假设您的服务仅从 id 返回一个交易,那么您正在为每个交易构建一个Observable,而我假设您想要的是一个Observable,它将随着时间的推移发出交易。您还必须不断地重新订阅新的deal$。以前的Subscription 将继续听旧的deal$ 并且永远不会得到新的值。

export class DealRouterComponent implements OnInit {

  ngOnInit() {
    this.deal$ = this.route.params.flatMap(params => 
      this.dealsService.getDeal(this.dealId = params['id'])
    );  
  }
}

这样每次路由的参数更新时deal$ 都会从您的服务中发出新的交易。

【讨论】:

  • 谢谢。您的回答确实帮助我理解了这一点。
猜你喜欢
  • 1970-01-01
  • 2023-01-30
  • 2023-03-23
  • 2021-07-04
  • 2019-10-03
  • 2019-02-24
  • 2023-01-11
  • 2018-11-27
  • 2020-08-18
相关资源
最近更新 更多