簡體   English   中英

Empty 未在 rxjs 中完成觀察

[英]Empty does not complete observable in rxjs

import { of, timer, EMPTY } from "rxjs"
import { concatMap, takeUntil, tap, switchMapTo } from "rxjs/operators"


of(1,2,3,4,5).pipe(
concatMap(val => {
    return timer(0, 1000).pipe(
        takeUntil(timer(3000)),
        switchMapTo(EMPTY)
    )
})
).subscribe()

此代碼需要 15 秒才能運行。 我想當返回 EMPTY 時,它會將可觀察的計時器標記為完成並停止發射。 並且那個 concatMap 應該立即接受下一個值。 所以我的期望是它應該需要 0 秒。

編輯:

我的具體示例與輪詢請求有關,如果我得到一個不好的響應就退出。 本質上覆蓋了指定的 takeUntil。

of([header1, header2, ...]).pipe(
concatMap(header => {
    const response1 = axios.get(...use header here)
    return timer(0, 1000).pipe(
        takeUntil(timer(3000)),
        switchMapTo(of(makeRequest(...based on response1))),
        // here i want to filter the values that the second request 
        // gets and make sure they are OK.
        // if they are not okay i want to get a new header, which 
        // leads 
        // to new response1 which leads to new makeRequests
        // so i want to essentially bail out before takeUntil if i get 
        //a bad response.
    )
}),
).subscribe(). 

編輯 2

我使用 takeUntil 和 takeWhile 解決了它,被觸發的將覆蓋另一個!

使用這樣的代碼:

import { Component } from "@angular/core";
import { of, timer, EMPTY } from "rxjs";
import { concatMap, takeUntil, tap, switchMapTo } from "rxjs/operators";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular";

  constructor() {
    of(1, 2, 3)
      .pipe(
        tap(x => console.log('Emitted value: ', x)),
        switchMapTo(EMPTY))
      .subscribe({
        next: x => console.log('Result: ', x),
        error: err => console.log('Error: ' , err),
        complete: () => console.log('Complete')
      });
  }
}

我得到以下結果:

Emitted value: 1
Emitted value: 2
Emitted value: 3
Complete

所以switchMapTo(EMPTY)似乎沒有完成源 stream。

Stackblitz 這里: https://stackblitz.com/edit/angular-empty-deborahk

你想用你的代碼完成什么?

這兩個代碼片段大致相同。

of(1,2,3,4,5).pipe(
  concatMap(_ =>
    timer(0, 1000).pipe(
      takeUntil(timer(3000)),
      switchMapTo(EMPTY)
    )
  )
).subscribe()
of(1,2,3,4,5).pipe(
  concatMap(_ =>
    timer(0, 1000).pipe(
      takeUntil(timer(3000)),
      filter(_ => false)
    )
  )
).subscribe()

switchMapTo(EMPTY) :任何到達管道這一點的值都將被忽略並轉換為立即完成的 stream。

switchMap內部時,完成不會導致switchMap完成。 它只會等待 map 的另一個值和一個新的 stream 訂閱。

你想達到什么目的?


更新:關於timer

大多數情況下,這些將是相同的:

timer(0, 1000).pipe(
  takeUntil(timer(2100))
).subscribe(console.log);

timer(0, 1000).pipe(
  takeUntil(timer(3000))
).subscribe(console.log);

timer(3000)的第一次發射和timer(1,1000)的第四次發射在技術上落在同一毫秒。 因為 JavaScript 不能保證這些延遲的管理精度,所以一些設置將采用第 4 個值,而一些(大多數)則不會。

甚至可能發生的事情取決於事件循環當前的繁忙程度。

如果您的實際代碼使用該設置,我建議您改用take(number)

timer(0, 1000).pipe(
  take(3)
).subscribe(console.log);

暫無
暫無

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

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