奇怪的takeUntil在rxjs 6中表现

时间:2018-10-21 06:32:00

标签: reactjs rxjs6

首先,停止开始按钮,然后单击restore01按钮和restore02按钮,恢复开始按钮,

然后,该错误是单击停止按钮01或停止按钮02时应停止该停止按钮,而不是

注意console.log,启动时停止启动按钮,然后单击restore01和restore02,然后启动按钮开始工作,现在当我单击控制台中的stop01按钮或stop02按钮时,该错误就像冬天一样到来。记录它显示停止流Array [“ r”,“”],但是开始按钮仍然有效,没有停止,您能想象我对这种情况的感觉吗?哦,天哪

online demo

代码很烂

const startDom = document.querySelector("#start")
const numberDom = document.querySelector("#number")
const restoreDom01 = document.querySelector("#restore01")
const stopDom01 = document.querySelector("#stop01")
const restoreDom02 = document.querySelector("#restore02")
const stopDom02 = document.querySelector("#stop02")

let init01 = false
let init02 = false

const origin01$ = new rxjs.Subject()
const origin02$ = new rxjs.Subject()

const restore01$ = rxjs.fromEvent(restoreDom01, "click")
restore01$.subscribe(() => origin01$.next("r"))
const stop01$ = rxjs.fromEvent(stopDom01, "click")
stop01$.subscribe(() => origin01$.next(""))

const restore02$ = rxjs.fromEvent(restoreDom02, "click")
restore02$.subscribe(() => origin02$.next("r"))
const stop02$ = rxjs.fromEvent(stopDom02, "click")
stop02$.subscribe(() => origin02$.next(""))

const [stopReg$, right$] = rxjs
.combineLatest(origin01$, origin02$)
.pipe(rxjs.operators.partition(arr => arr.some(isEmpty)));
const restoreReg$ = right$.pipe(
  rxjs.operators.take(1),
  rxjs.operators.repeatWhen(() => stopReg$)
);


const start$ = rxjs.fromEvent(startDom, "click");
start$
  .pipe(
  rxjs.operators.mapTo(1),
  rxjs.operators.scan((acc, cur) => acc + cur, 0),
  rxjs.operators.takeUntil(stopReg$),
  rxjs.operators.repeatWhen(() => restoreReg$)
)
  .subscribe(x => (numberDom.innerHTML = x));


stopReg$.subscribe(x => console.log("stop stream", x));
restoreReg$.subscribe(x => console.log("restore stream", x));

origin01$.next("")
origin02$.next("")

function isEmpty(n) {
  return n === "";
}

可能不是很清楚,所以我告诉你步骤

  1. 单击2个还原按钮,一个一个

  2. 单击开始按钮,单击后将看到数字加一。

  3. 单击停止按钮,确定,这是一个问题,现在应该停止启动按钮,但是,您仍然可以添加一个来单击启动按钮,但是在控制台中可以看到停止流已订阅,很奇怪

I also have other demo with the same problem using react and rxjs

1 个答案:

答案 0 :(得分:1)

您可能遇到的问题是如何使用combineLatestSubject

combineLatest(origin01$, origin02$)

其中origin01$origin02$均为Subject。主题自然不会保留旧的值来发出,它们本质上只是“事件发出者”,它们会将其发出的内容广播给订户,仅此而已,他们不再持有该值。

origin01$触发时,combineLatest似乎也必须等待另一个Subject再次触发才能发出信号。您的stopReg$流可能未如预期的那样触发,请使用tap进行检查,如下所示:

rxjs.operators.repeatWhen(() => 
  stopReg$.pipe(
    rxjs.operators.tap(x => console.log('got to here'))
  )
)

BehaviorSubject在这里可以提供帮助。这是RxJS docs的描述:

  

Subject的变体,它需要一个初始值并发出其   订阅时返回当前值。

如果将原点Subject切换为BehaviorSubject,则可能会得到期望的结果。我尝试过:

const origin01$ = new rxjs.BehaviorSubject("")
const origin02$ = new rxjs.BehaviorSubject("")

仅点击“停止”按钮之一后,我无法看到“开始”扫描流在单击时继续对值求和。

我认为这是可行的,因为在combineLatest中,因为它是BehaviorSubject,所以它已经能够获取最新值,而不必等待其他{{1 }}。