Javascript 如何使用2个可观察对象发出的值作为http请求的参数,1个可观察对象将另一个重置为默认值?

Javascript 如何使用2个可观察对象发出的值作为http请求的参数,1个可观察对象将另一个重置为默认值?,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我订阅了一个基于其他两个观测值的映射观测值。每当这两个元素中的任何一个发出一个值时,我希望映射的可观察对象发出 无论何时外部可见光发射,内部可见光值都应重置为默认值(示例中为0)。问题是,当我重置内部值时,会发出一个额外的值 (对于上下文-这两个可观测值为http请求提供参数,http请求是映射的可观测值。新的外部值应将内部值重置为0) const outer=新主题(); const-inner=新行为主体(0); 常量http=of(“”); 设mapped=outer.pipe( 轻触((

我订阅了一个基于其他两个观测值的映射观测值。每当这两个元素中的任何一个发出一个值时,我希望映射的可观察对象发出

无论何时外部可见光发射,内部可见光值都应重置为默认值(示例中为0)。问题是,当我重置内部值时,会发出一个额外的值

(对于上下文-这两个可观测值为http请求提供参数,http请求是映射的可观测值。新的外部值应将内部值重置为0)

const outer=新主题();
const-inner=新行为主体(0);
常量http=of(“”);
设mapped=outer.pipe(
轻触(()=>inner.next(0)),
开关映射(outerVal=>{
返回inner.pipe(map(innerVal=>({innerVal,outerVal}));
}),
开关映射({innerVal,outerVal})=>{
返回http.pipe(点击(()=>console.log(“http:”,outerVal,innerVal));
})
);
已映射。订阅(结果=>{
控制台日志(结果);
});
外部。下一个(“第一个”);
下一步(1);
内。下(2);
外部。下一个(“第二个”);
下一步(3);
//http:第一个0
//http:first1
//http:first2

//http:first 0下面是您想要的输出。我不确定它是否符合你的标准。你的内在可观察物必须是行为主体,这有什么原因吗?如果只是给它一个初始值,那么
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
的工作方式)。

考虑下面的方法,其中我将两个
可观察的
流和过滤器结合起来,只发出1个值。然后,我们可以使用新的流与http请求合并


常量http=of(“”);
const triggerSubject$=new BehaviorSubject({inner:0,outer:null});
const trigger=triggerSubject$.pipe(
过滤器({内部,外部})=>内部和外部)
);
常量triggerInner=val=>{
console.log(“内部”,val);
返回triggerSubject$。下一步({
内线:瓦尔,
外部:triggerSubject$.value.outer
});
};
常量triggerOuter=val=>{
控制台日志(“外部”,val);
返回triggerSubject$.next({inner:0,outer:val});
};
const mapped=trigger.pipe(
开关映射({inner:innerVal,outer:outerVal})=>
管道(点击(()=>console.log(“http:”,outerVal,innerVal)))
)
);
已映射。订阅(结果=>{
控制台日志(结果);
});
触发外部(“第一”);
触发器内部(1);
触发器内部(2);
触发外部(“第二”);
触发器内部(3);

tap(() => {
  inner2.complete();
  inner2 = new BehaviorSubject(0);
}),