[英]Why does operator in piped Subject is called for every subscription?
我需要過濾來自 Subject 的值並對返回的數據做一些副作用。
像這樣的東西:
const subject2 = subject.pipe(
filter((value: number) => {
console.log(`filter: ${value}`);
return value % 2 === 0; // filter even nubmers
}),
tap((value) => console.log(`after filter: ${value}`))
);
我看到來自filter()
的 function 被調用用於發送給subject2
訂閱者的每個值(即與subject2
訂閱者長度一樣多)。 但我假設每次next()
調用都會調用一次。
我還看到,如果我訂閱subject2
和 pipe 它的值,則不會出現重復。
有人可以解釋一下幕后發生的事情以及過濾主題值的正確模式是什么?
Stackblitz 上的示例:
https://stackblitz.com/edit/typescript-e4stc4?devtoolsheight=100&file=index.ts
在幕后,Subject 的next
方法是這樣實現的:
for (const observer of this.observers) {
observer.next(value);
}
因此,每個“觀察者”(或“訂閱者”)在您發送到主題時都會收到自己的通知。 運算符只是在將結果傳遞給觀察者之前處理value
的函數。
例如,如果您這樣聲明運算符:
const myFilter = filter((value: number) => value % 2 === 0);
const myTap = tap((value) => console.log(`after filter: ${value}`));
然后自定義 Subject 中的next
function 可以這樣實現:
for (const observer of this.observers) {
observer.next(myTap(myFilter(value)));
}
(此代碼實際上不起作用 - 它是一種簡化,以顯示當您在主題上調用next
時值如何到達訂閱者)
為了解決您的問題,您可以通過將share()
作為鏈的最后一個元素來減少源 Subject 的觀察者數量,如下所示:
const subject2 = subject.pipe(
filter((value: number) => {
console.log(`filter: ${value}`);
return value % 2 === 0; // filter even nubmers
}),
tap((value) => console.log(`after filter: ${value}`)),
share()
);
share
是這樣實現的,無論有多少觀察者訂閱它,它都充當源 Observable 的單個觀察者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.