Rxjs: flatMap 中的 Subject 属性,避免意外触发
Rxjs: proper of Subject inside flatMap to avoid unexpected triggering
我有一个 Angular "Quiz" 应用程序并使用 rxjs 5.5.2 来实现具有某些业务逻辑的服务。我的 rxjs 流程出现问题,导致多次意外执行函数。
重现步骤:
- 调用 startNewQuiz 将新测验设置为活动
- 多次调用 answerQuestion 来回答测验问题。每个答案都会触发构造函数中定义的流程
- 再次调用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);
}
}
你应该在你的第一个 flatMap
中使用 first 运算符
flatMap(
() => this.activeQuiz$.first()
)
由于 activeQuiz 是一个主题,它可以发出多次。 (第 3 步中发生了什么),但是您只关心获得活动测验(1 个值)。首先,您只会收听 1 value/emission.
我有一个 Angular "Quiz" 应用程序并使用 rxjs 5.5.2 来实现具有某些业务逻辑的服务。我的 rxjs 流程出现问题,导致多次意外执行函数。
重现步骤:
- 调用 startNewQuiz 将新测验设置为活动
- 多次调用 answerQuestion 来回答测验问题。每个答案都会触发构造函数中定义的流程
- 再次调用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);
}
}
你应该在你的第一个 flatMap
中使用 first 运算符flatMap(
() => this.activeQuiz$.first()
)
由于 activeQuiz 是一个主题,它可以发出多次。 (第 3 步中发生了什么),但是您只关心获得活动测验(1 个值)。首先,您只会收听 1 value/emission.