javascript - 如何使用 2 个 observable 发出的值作为 http 请求的参数,其中 1 个 observable 将另一个设置为默认值?
问题描述
我正在订阅基于其他 2 个可观察对象的映射可观察对象。每当 2 中的任何一个发出一个值时,我都希望映射的 observable 发出。
每当外部可观察值发出时,内部可观察值应重置为默认值(示例中为 0)。问题是当我重置内部值时,会发出一个额外的值。
(对于上下文 - 2 个 observable 为 http 请求提供参数,这是映射的 observable。新的外部值应将内部值重置为 0)
const outer = new Subject();
const inner = new BehaviorSubject(0);
const http = of("");
let mapped = outer.pipe(
tap(() => inner.next(0)),
switchMap(outerVal => {
return inner.pipe(map(innerVal => ({ innerVal, outerVal })));
}),
switchMap(({ innerVal, outerVal }) => {
return http.pipe(tap(() => console.log("http: ", outerVal, innerVal)));
})
);
mapped.subscribe(result => {
console.log(result);
});
outer.next("first");
inner.next(1);
inner.next(2);
outer.next("second");
inner.next(3);
// http: first 0
// http: first 1
// http: first 2
// http: first 0 <--- extra
// http: second 0
// http: second 3
我知道它为什么会发生,但我不知道如何处理它。我有一个解决方案可以在这个 stackblitz 的底部得到正确的结果,但我认为它会导致内存泄漏。
解决方案
以下具有您想要的输出。我不确定它是否符合您的标准。你的内在可观察物必须是行为主体,有什么理由吗?如果只是给它一个初始值,那么startWith
操作员会做得更干净。
const outer = new Subject();
const inner = new Subject();
const http = of("");
const mapped = outer.pipe(
switchMap(outerVal =>
inner.pipe(
startWith(0),
map(innerVal => ({ innerVal, outerVal }))
)
),
switchMap(({ innerVal, outerVal }) =>
http.pipe(
tap(() => console.log("http: ", outerVal, innerVal))
)
)
);
mapped.subscribe(console.log); // ""
你的 stackblitz 内存泄漏
您正在创建长期存在的多播流并且从未完成它们。你可以试试:
tap(() => {
inner2.complete();
inner2 = new BehaviorSubject(0);
}),
SwitchMap 将取消订阅,但多播流不会在取消订阅时完成(取决于它的refcount
工作方式)。
推荐阅读
- php - 在 Codeigniter 中用不同的变量名替换 default_controller
- php - Artisan::call 输出 php-fpm 帮助文本
- sql - 如何使用 SQL 查询将一个月的全天名称显示为列以在报告中显示
- r - 当它们是“因素”时,从 R 中的数据框中提取字符串列
- model-view-controller - 如何在取消选择时更改剑道图表图例项目颜色?
- laravel - 在 laravel vue 中检查用户状态
- html - 使用 css 命令更改选项卡标题
- android - 当没有唯一的 id/类名时,如何在 appium 中选择复选框?
- python - 使用 pandas.read_csv 读取文件名中包含 str() 的文件
- ns2 - NS2:接收数据包为零