簡體   English   中英

無法用 RxJS 中的計時器完成比賽

[英]Cannot finish a race with timer in RxJS

race(
  timer(2000).pipe(mapTo(1)),
  timer(1000).pipe(mapTo(2)),
).toPromise().then(r => console.log(r))

上面的代碼將 output 2

如果我有一個操作嘗試重復直到滿足條件,但如果花費時間太長則忽略它,那么我會在這個答案https://stackoverflow.com/a/51644077中采取一種方法

問題是race永遠不會以最短的 function 結束。 longActionObservable重復,直到滿足條件並調用empty()

const o = longActionObservable();
race(
  o.pipe(expand(v => v < 100 ? empty() : o)), // no toArray because I do not need result
  timer(2000),
).toPromise()

此代碼不會返回將永遠解決的 promise。 我想知道為什么這種方法對這種行為如此脆弱? 如果有一個可觀察的timer(2000)肯定會結束,為什么比賽不結束?

您錯過了有關race的重要一點:

使用最先發射的可觀察對象

這意味着如果longActionObservable的第一次發射發生在計時器之前,則不使用計時器,無論“擴展”可觀察對象需要多長時間才能完成。

沒有 toArray 因為我不需要結果

即使您不需要結果, toArray實際上也會按照您的意願進行這項工作,因為在您的“擴展”可觀察對象完成之前它不會允許任何排放。 您可以使用reduce而不是使用toArray

race(
  o.pipe(
    expand(v => v < 100 ? empty() : o), 
    reduce(() => undefined)
  ),
  timer(2000),
)
.toPromise()

如果有一個可觀察的計時器(2000)肯定會結束,為什么比賽不結束?

比賽不會結束的唯一原因是因為選擇的源(第一個可觀察到的發射)沒有完成。 檢查你的可觀察擴展的排放量,看看它為什么沒有完成:

  o.pipe(
    expand(v => v < 100 ? empty() : o),
    tap(v => console.log('expand: ', v)),
    reduce(() => undefined)
  ),

這是您可以玩的StackBlitz :-)

暫無
暫無

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

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