簡體   English   中英

Rxjs:concatMap 中的條件延遲

[英]Rxjs: conditional delay in concatMap

我想要實現的是:

我想立即在我的頁面上顯示一條消息(並在其容器上觸發 animation),除非前一條消息在不到 8 秒前被觸發。 在這種情況下,等待 8 秒過去並觸發第二個 observable。

我想我必須使用concatMapdelay運算符,但我正在努力尋找正確的組合。

這是我得到的最接近的嘗試:

    this.message$ = this.messageService.message.pipe(
      concatMap((msg) => {
        return of(msg).pipe(
          tap(() => {
            const messageTween = gsap.fromTo(
              "#message",
              { opacity: 0 },
              { opacity: 1, duration: "0.5" }
            );
            messageTween.reverse().delay(5);
          }),
          delay(8000)
        );
      })
    );

在這里我得到了正確的圖形效果,但是message的值在 8 秒后更新。

你能幫助我嗎?

您快到了。

  1. delay必須高於觸發 animation 的tap操作符。 請注意,管道運算符的順序會影響修改后的 observables 鏈。

  2. 僅當當前發射在 8 秒內時,您才可以使用timestamp運算符來強制執行延遲。

this.message$ = this.messageService.message.pipe(
  timestamp(),
  concatMap(({timestamp, value}) =>
    Date.now() - timestamp < 8000 ? of(value) : of(value).pipe(delay(8000));
  ),
  tap(() => {
    const messageTween = gsap.fromTo(
      "#message",
      { opacity: 0 },
      { opacity: 1, duration: "0.5" }
    );
    messageTween.reverse().delay(5);
  })
);

但是您的邏輯可能存在內在錯誤。 假設自第一次發射以來已經過去了 5 秒。 由於誘導延遲與當前時間戳而不是先前發射的時間戳進行比較,因此第二次發射將總共延遲 13 秒。 為了解決這個問題,您可以緩存上一個發射的時間戳是一個變量,並將當前發射的時間戳與其進行比較,而不是Date.now()

你可以delay一個EMPTY observable 來創建一個等待一段時間然后完成的 observable。 將其與另一個 observable 合並以組成一個在完成前具有最短運行時間的 observable。

這可能是這樣的:

// Helper Function
const gsapMakeOpaque = _ => gsap.fromTo(
  "#message",
  { opacity: 0 },
  { opacity: 1, duration: "0.5" }
).reverse().delay(5);

// Solution
this.message$ = this.messageService.message.pipe(
  concatMap(msg => merge(
    of(msg).pipe(tap(gsapMakeOpaque)),
    EMPTY.pipe(delay(8000))
  ))
);

由於您的第一個 observable 只是您已經擁有價值的 singleton,因此您可以進一步簡化它。 創建一個在 8 秒后完成的可觀察對象,並使用您的startWith值啟動它。

這可能看起來像這樣:

this.message$ = this.messageService.message.pipe(
  concatMap(msg => EMPTY.pipe(
    delay(8000),
    startWith(msg),
    tap(gsapMakeOpaque)
  ))
);

暫無
暫無

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

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