【问题标题】:Managing subscriptions based on async event基于异步事件管理订阅
【发布时间】:2020-09-11 08:59:30
【问题描述】:

我正在寻找一种方法来简化这一点并避免在我的管道中管理订阅。

关于我的代码的总体思路:

this.start$ubject // waiting for users call to start
  .pipe(
    mergeMap(() => from(this.thirdPartyService.start())), // now i need to wait for smth to start
    tap(() => {
      // only after thirdPartyService started i can subscribe because prior to that they are undefined
      this.subscriptions.push(
        this.thirdPartyService.alfa$.subscribe(this.first$ubject),
        this.thirdPartyService.beta$.subscribe(this.second$ubject),
      );
    }),
  );

有什么办法可以解决吗? takeWhile 之类的东西,但要订阅?

【问题讨论】:

  • 我有一些问题: start$ubject 会发出多少次值?当它在this.thirdPartyService.start()、alfa$ 和beta$ 完成之前多次发射时,它将多次运行thirdPartyService。所以首先,这是你想要的。有一种方法可以管理您的订阅。您可以使用 zip 运算符代替选项卡。
  • 有必要将您的订阅推送到 this.subscriptions 中吗?很抱歉所有这些问题。正确解决问题也很重要。
  • @SerkanSipahi start$ubject 将发出多次,每次我需要启动该服务并收到唯一的alfa$ 和 beta$

标签: asynchronous rxjs rxjs5 rxjs6


【解决方案1】:

这样试试:

// waits for start$ubject, then waits for thirdPartyService, then starts.
this.subscriptions.push(
  this.start$ubject.pipe(
    switchMap(() => from(this.thirdPartyService.start())), // waiting start
    switchMap(() => merge( // listening on both of the streams
      this.thirdPartyService.alfa$.pipe(
        tap(this.first$ubject),
      ),
      this.thirdPartyService.beta$.pipe(
        tap(this.second$ubject),
      ),
    )),
  ).subscribe(),
);
// waits for start$ubject or for thirdPartyService, then starts.
this.subscriptions.push(
  merge(this.start$ubject, from(this.thirdPartyService.start()).pipe(
    switchMap(() => merge( // listening on both of the streams
      this.thirdPartyService.alfa$.pipe(
        tap(this.first$ubject),
      ),
      this.thirdPartyService.beta$.pipe(
        tap(this.second$ubject),
      ),
    )),
  ).subscribe(),
);

【讨论】:

  • 我不能使用 merge,因为它会合并我的 observables,我需要对 alpha$ 和 beta$ 发射采取不同的行动。
  • 为什么?此流有一个忽略发射的空订阅。如果您想对alpha$ 和beta$ 采取行动,只需使用tap。我已经更新了答案。
  • 当用户需要通过发射到 start$ubject 来重新启动这个服务?我应该使用switchMap而不是exhaustMap吗?
  • 是的。但是您需要更改序列,目前它等待this.start$ubject,然后等待this.thirdPartyService.start(),然后开始序列。如果您想在每次发出this.start$ubject 和this.thirdPartyService.start() 时重新启动它 - 然后使用 switchMap,如果这两个中的任何一个都可以触发启动,那么在此处使用合并。我会更新答案
  • 他们都在等待。问题是它发出后你想做什么。因为使用 switchMap 它使用合并映射取消订阅旧流,所以它创建了第二个流,所以每次发出都会导致在调用 mergeMap 时多次触发 alpha beta。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多