【问题标题】:Rxjs: proper of Subject inside flatMap to avoid unexpected triggeringRxjs:在 flatMap 中正确的 Subject 以避免意外触发
【发布时间】:2018-01-19 20:53:11
【问题描述】:

我有一个 Angular “测验”应用程序并使用 rxjs 5.5.2 来实现具有一些业务逻辑的服务。我的 rxjs 流程存在问题,导致函数多次意外执行。

复制步骤:

  1. 调用 startNewQuiz 将新测验设置为活动状态
  2. 多次拨打answerQuestion 来回答测验问题。每个答案都会触发构造函数中定义的流程
  3. 再次调用 startNewQuiz 开始另一个测验

问题在于,在第 3 步调用 startNewQuiz 会多次触发 doStuffWithQuiz。调试表明这是因为 this.activeQuiz$ 在第 3 步发出了一个值并触发了 doStuffWithQuiz。由于我在第 2 步之前已经多次调用 answerQuestion - doStuffWithQuiz 也多次调用。在流程中使用 activeQuiz$ 的唯一原因是获取当前测验并将其传递给管道。

我希望我的 answerQuestionSubject 流程仅在我将某些内容推送到 answerQuestionSubject 时执行,并避免在将某些内容推送到 时触发 doStuffWithQuiz >activeQuiz$.

那我该如何完成呢?

export class QuizFlowService {

  // to keep current active quiz
  private activeQuiz$ = new ReplaySubject<Quiz>(1);

  private answerQuestionSubject = new Subject<Answer>();

  ....

  constructor() {
    // setup flow for answers
    this.answerQuestionSubject.pipe(
      flatMap(
          // this is just to get active quiz and pass it futher
          () => this.activeQuiz$
      ),
      flatMap((quiz) => {
        // it is called multiple time on step 3
        doStuffWithQuiz(quiz)
      })
    ).subscribe();
  }

  // starts new quiz
  startNewQuiz(quiz: Quiz) {
    this.activeQuiz$.next(quiz);
  }

  // triggers answer flow
  answerQuestion(answer: Answer) {
    this.answerQuestionSubject.next(answer);
  }
}

【问题讨论】:

    标签: angular typescript rxjs5


    【解决方案1】:

    您应该在您的第一个 flatMap 中使用 first 运算符

    flatMap(
        () => this.activeQuiz$.first()
    )
    

    由于 activeQuiz 是一个主题,它可以发出多次。 (步骤 3 中发生了什么),但是您只关心获取活动测验(1 值)。首先,您将只收听 1 个值/发射。

    【讨论】:

      猜你喜欢
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2018-06-26
      • 2012-03-08
      • 1970-01-01
      相关资源
      最近更新 更多