Angular 如何嵌套多个观察对象/订阅 1.问题

Angular 如何嵌套多个观察对象/订阅 1.问题,angular,typescript,firebase,rxjs,Angular,Typescript,Firebase,Rxjs,我正在尝试为我的博客创建一个不断变化的语言流,总之,这就是它的样子: 用户单击触发事件(主题)的按钮,即语言更改 此语言更改用于查询Firebase,以获得基于该语言的正确页面 如果我单独执行每个步骤,然后用户更改语言,则不会触发查询,因为它不知道刚刚发生了事件。所以我认为这应该是某种嵌套订阅/可观察的。我错了吗 2.到目前为止我的代码 我尝试过嵌套订阅,但没有成功。我相信这是因为范围问题。现在,这就是我正在尝试的: this.headerService.langChanged.pipe( 地图

我正在尝试为我的博客创建一个不断变化的语言流,总之,这就是它的样子:

  • 用户单击触发事件(
    主题
    )的按钮,即语言更改
  • 此语言更改用于查询
    Firebase
    ,以获得基于该语言的正确页面
  • 如果我单独执行每个步骤,然后用户更改语言,则不会触发查询,因为它不知道刚刚发生了事件。所以我认为这应该是某种嵌套订阅/可观察的。我错了吗

    2.到目前为止我的代码 我尝试过嵌套订阅,但没有成功。我相信这是因为范围问题。现在,这就是我正在尝试的:

    this.headerService.langChanged.pipe(
    地图(
    (newLang:string)=>{
    这个是.db
    .收藏(
    此.aboutMeCollectionName,
    ref=>ref.where('lang','=',newLang)
    )
    .valueChanges();
    })
    )
    .订阅(
    值=>{
    this.aboutMe=值[0]
    }
    );
    
    headerService.langChanged
    是一个
    主题


    这个用例是否有
    rxjs
    操作符
    concat
    似乎是一个很好的候选者,但它会等待前一个
    可观察的
    结束,而在本例中它不会这样做。还有一个事实是,我必须将参数传递到下一个可观察的对象上……

    我认为使用
    concat
    switchMap
    merge
    forkJoin
    等任何一种方法都可以找到有效的解决方案。这实际上取决于您希望从它们中获得的一些小东西,比如并发性。我在这里使用
    forkJoin
    组合了一个小的Stackblitz示例:

    您可以在控制台日志中看到每个内部
    可观察到的
    的不同计时,以验证使用
    forkJoin
    是否具有该计时,从而只需要最慢的可观察时间

    以及我的订阅:

    this.langchange
    .订阅(newLang=>{
    log(`language changed${newLang}`);
    this.cancelangchange.next();
    分叉连接(
    这个.getUserName(newLang),
    这个.getUserBio(newLang),
    this.getUserCreationDate(newLang)
    )
    .pipe(takeUntil(本次变更))
    .subscribe(([username,bio,userCreationDate])=>{
    this.aboutMe.username=用户名;
    this.aboutMe.bio=bio;
    this.aboutMe.userCreationDate=userCreationDate;
    });
    });
    

    我还添加了第二个
    主题
    取消更改
    ,这意味着如果用户在加载第一个更改时选择了另一种语言,就可以取消
    forkJoin
    订阅。

    我基本上通过使用
    管道
    映射
    使其正常工作。
    map
    操作将使用第一个可观察对象根据前者的参数生成另一个可观察对象。然后我们以嵌套的方式订阅,这将最终为我们提供所需的数据

    this.aboutMeSubscription=this.headerService.langChanged.pipe(
    地图(
    (newLang:string)=>{
    返回这个.db
    .收藏(
    此.aboutMeCollectionName,
    ref=>ref.where('lang','=',newLang)
    )
    .valueChanges();
    })
    )
    .订阅(
    langChangedAboutMeObs=>{
    this.langChangedSubscription=langChangedAboutMeObs
    .订阅(
    (值:AboutDepage[])=>{
    this.aboutMe=值[0];
    }
    );
    }
    );
    

    我还将我的
    Subject
    更改为
    BehaviorSubject
    ,这样即使在用户做任何事情之前,也会发出一个初始值。最后,在
    ngondestory

    Try
    switchMap()
    上取消订阅这两个订阅很重要,每次更改输入语言时,它都会调用API并请求新的可观察项。为什么要
    take(1)
    ?听起来你不想只听第一次event@Freddy,斑点很好。这可能让人想起我在这方面的许多尝试。在你发布这个答案之前,我刚刚设法在这里使它起作用。我使用
    pipe
    map
    让语言observeable每次语言变化时都返回另一个observeable给我;然后我订阅它,在里面,我订阅返回的可观察对象。(听起来比代码本身更复杂…)你认为我的解决方案有什么问题吗?(我在
    ngondestory
    上都退订了)没什么大不了的,应该没问题。我唯一关心的是,用户是否有可能更改两次语言,而第二个可观察到的在第一个之前完成。你最终可能会得到第一个人的数据。但这种情况可能无论如何都不太可能。我会接受你的答案,但稍后也会发布我的答案。