簡體   English   中英

RxJS - 一個 observable 'A' 不會停止發射從同一個 observable 'A' 傳送的 takeUntil

[英]RxJS - An observable 'A' doesn't stop emitting with a takeUntil that is piped from the same observable 'A'

我有一個可觀察的,在單擊開始按鈕后每秒向控制台打印一個數字。 單擊開始按鈕 5 秒后,可觀察對象應停止打印。

單擊開始按鈕后每秒開始條件

點擊開始按鈕五秒后結束條件

不起作用的代碼

const startClick$ = fromEvent(document.getElementById('start'), 'click');
const stop$ = startClick$.pipe(switchMapTo(interval(5000)));
const printInterval$ = interval(1000).pipe(takeUntil(stop$));
const startPrint$ = startClick$.pipe(switchMapTo(printInterval$));

startPrint$.subscribe(
  value => {
    console.log('new value is:', value);
  },
  () => {
    console.log('there was some error!');
  },
  () => {
    console.log('i have completed');
  }
);

stop$.subscribe(() => {
  console.log('i should stop right now!!');
});

單擊開始按鈕后五秒鍾后,startPrint$ Observable 不會停止發射。

有效的代碼

const endClick$ = fromEvent(document.getElementById('end'), 'click');
const stopWithEndClick$ = endClick$.pipe(switchMapTo(interval(5000)));
const printInterval1$ = interval(1000).pipe(takeUntil(stopWithEndClick$));
const startPrint1$ = startClick$.pipe(switchMapTo(printInterval1$));

startPrint1$.subscribe(
  value => {
    console.log('1: new value is:', value);
  },
  () => {
    console.log('1: there was some error!');
  },
  () => {
    console.log('1: i have completed');
  }
);

stopWithEndClick$.subscribe(() => {
  console.log('1: i should stop right now!!');
});

在這里,我有另一個按鈕end ,我在單擊 end 按鈕后 5 秒內執行。 在這種情況下,observable 會按預期停止發射。

我怎樣才能使第一個案例工作,我在這里犯了任何錯誤嗎? 整個工作代碼可以在https://stackblitz.com/edit/take-until-issue?file=index.ts 找到

發生這種情況是因為 RxJS 運算符中的訂閱順序。 當您第一次單擊“開始”按鈕時,第一個收到通知的是stop$ ,但沒有人在收聽stop$ ,因此通知不會觸發任何內容。 你看到"'i should stop right now!!' 只是因為你最后自己訂閱了。

因此,最簡單的解決方案是將stop$鏈創建為一個 Observable,它只會在您訂閱后開始發射,例如timer(5000) ,它只發射一次然后完成。

const stop$ = timer(5000);

您更新的演示: https://stackblitz.com/edit/take-until-issue-or4okm?file=index.ts

請注意,您可能會得到不同數量的結果,因為 RxJS (通常是 JavaScript)不能保證5000ms正好是5000ms 這同樣適用於1000ms ,因此有時事件可能會以不同的順序觸發。 如果您只想要 5 個結果,則更好地使用例如take(5) 此外,對於日志記錄,最好使用例如tap(v => console.log(v))這樣您就不會再次訂閱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM