[英]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.