内側のオブザーバブル(mergeMapまたはswitchMapオペレーターで定義されているものなど)は、外側のオブザーバブルにサブスクリプションが残っていなくても「停止」しないことに気づきました。
より良い例として、いくつかのコードを示しましょう。
const {
Subject,
of: obsOf,
concat: obsConcat,
defer,
} = require("rxjs");
const {
finalize,
mergeMap,
tap,
takeUntil,
} = require("rxjs/operators");
const subject = new Subject();
obsOf(null).pipe(
mergeMap(() =>
obsConcat(
defer(() => {
console.log("side-effect 1");
return obsOf(1);
}),
defer(() => {
console.log("side-effect 2");
return obsOf(2);
}),
defer(() => {
console.log("side-effect 3");
return obsOf(3);
})
)
),
finalize(() => {
console.log("finalized");
})
)
.pipe(
takeUntil(subject),
tap((i) => {
if (i === 2) {
subject.next();
}
})
).subscribe(
(i) => { console.log("next", i); },
(e) => { console.log("error", e); },
() => { console.log("complete"); },
);
// Ouput:
// > side-effect 1
// > next 1
// > side-effect 2
// > complete
// > finalized
// > side-effect 3
side-effect 3
外側のオブザーバブルがすでにと呼ばれてfinalize
いるので、行がログに記録されるという事実は奇妙です。
これらの副作用はすべてdefer
に含まれているため、サブスクリプションを解除した後は完全に回避できます。私の観点からは、これらの副作用はまったく価値がありません。
RxJSがまだそれらを実行する理由はありますか?
残念ながら、これは設計によるものです(RxJS 6以降)-concat
オブザーバブルをバッファリングし、サブスクライブを解除した後でも、バッファリングされた各オブザーバブルをサブスクライブします(サブスクリプションのclosed
場合はサブスクライブしてすぐにサブスクライブを解除します)。
オブザーバブルがバッファリングされないようにする必要があります...
obsOf(null).pipe(
mergeMap(() => obsOf(
defer(() => {
console.log("side-effect 1");
return obsOf(1);
}),
defer(() => {
console.log("side-effect 2");
return obsOf(2);
}),
defer(() => {
console.log("side-effect 3");
return obsOf(3);
})
)),
concatAll(),
finalize(() => {
console.log("finalized");
}),
takeUntil(subject),
tap((i) => {
if (i === 2) {
subject.next();
}
})
).subscribe(
(i) => { console.log("next", i); },
(e) => { console.log("error", e); },
() => { console.log("complete"); },
);
上記のコードは機能すると考えることができますが、オブザーバブルの1つを遅らせるまでです。元に戻しobsOf(1)
てtimer(100).pipe(mapTo(1));
や行動はまったく同じです。
唯一の回避策は、何もバッファリングしていないことを確認するか(concat*
演算子を使用しないことを意味します)、または他の方法で監視可能なプロダクションを制限することです(別のサブジェクトを使用し、プロダクションを手動で制御します)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加