Rxjs 加上之前的结果,可观察的管道只运行一次

Rxjs 加上之前的结果,可观察的管道只运行一次,rxjs,rxjs5,rxjs6,Rxjs,Rxjs5,Rxjs6,我有一个过滤器数组作为一个可观察的,我想从中添加/删除过滤器。下面是我的代码,它当前仅在函数第一次运行时添加一个过滤器 第二次什么也没发生 private _filters$ = new BehaviorSubject<Filter[]>([]); addFilter(added: Filter) { debugger // adding to array of filters this._filters$.pipe( tap(d =>

我有一个过滤器数组作为一个
可观察的
,我想从中添加/删除过滤器。下面是我的代码,它当前仅在函数第一次运行时添加一个
过滤器

第二次什么也没发生

private _filters$ = new BehaviorSubject<Filter[]>([]);

addFilter(added: Filter) {
    debugger
    // adding to array of filters
    this._filters$.pipe(
        tap(d => { debugger; }),
        first(), 
        map(filters => ([...filters, added]))
    ).subscribe(this._filters$);
}

实际上,这是因为
首先
。当您第一次运行函数时,它正在创建流并订阅
BehaviorSubject
。当它接收到第一个事件时,它将其转发到
BehaviorSubject
,然后完成
BehaviorSubject
。第二次运行它时,
BehaviorSubject
已关闭,因此它会立即取消对它的任何新订阅

在不太了解您的实际目标的情况下,我的建议是,不要将
行为主体
放在管道的底部,而是将其放在管道的顶部

// You don't actually need the caching behavior yet so just use a `Subject`
private _filters$ = new Subject<Filter>()

// Hook this up to whatever is going to be using these filters
private _pipeline$ = this._filters.pipe(
  // Use scan instead mapping back into self
  scan((filters, newFilter) => ([...filters, newFilter]), []),
  // Store the latest value for new subscribers
  shareReplay(1)
);

// Now this method is just pushing into the `Subject` and the pipeline never has to be torn down
addFilter(added: Filter) {
    debugger
    this._filters$.next(added);
}
//实际上还不需要缓存行为,所以只需使用`Subject即可`
private _filters$=新主题()
//把它连接到使用这些过滤器的任何东西上
private _pipeline$=this.\u filters.pipe(
//使用扫描而不是映射回自我
扫描((过滤器,新过滤器)=>([…过滤器,新过滤器],[]),
//存储新订阅者的最新值
共享重播(1)
);
//现在,这种方法正进入“主题”,管道永远不必拆除
添加过滤器(添加:过滤器){
调试器
此._过滤器$.next(添加);
}

实际上,这是因为
首先
。当您第一次运行函数时,它正在创建流并订阅
BehaviorSubject
。当它接收到第一个事件时,它将其转发到
BehaviorSubject
,然后完成
BehaviorSubject
。第二次运行它时,
BehaviorSubject
已关闭,因此它会立即取消对它的任何新订阅

在不太了解您的实际目标的情况下,我的建议是,不要将
行为主体
放在管道的底部,而是将其放在管道的顶部

// You don't actually need the caching behavior yet so just use a `Subject`
private _filters$ = new Subject<Filter>()

// Hook this up to whatever is going to be using these filters
private _pipeline$ = this._filters.pipe(
  // Use scan instead mapping back into self
  scan((filters, newFilter) => ([...filters, newFilter]), []),
  // Store the latest value for new subscribers
  shareReplay(1)
);

// Now this method is just pushing into the `Subject` and the pipeline never has to be torn down
addFilter(added: Filter) {
    debugger
    this._filters$.next(added);
}
//实际上还不需要缓存行为,所以只需使用`Subject即可`
private _filters$=新主题()
//把它连接到使用这些过滤器的任何东西上
private _pipeline$=this.\u filters.pipe(
//使用扫描而不是映射回自我
扫描((过滤器,新过滤器)=>([…过滤器,新过滤器],[]),
//存储新订阅者的最新值
共享重播(1)
);
//现在,这种方法正进入“主题”,管道永远不必拆除
添加过滤器(添加:过滤器){
调试器
此._过滤器$.next(添加);
}

我应该先仔细检查一下
,我可能有另一个在我的真实代码中阻止了它。关于你的回答,我看到了一个问题和一个问题。问题是_pipeline$是我们订阅的,但它假设我们只添加了过滤器。而在我的情况下,我会删除/添加。问题是您是否使用了
shareReplay(1)
而不是在顶部使用
BehaviorSubject
,以避免订阅时的额外计算?对于您提到的问题,我建议您看看另一个SO问题,该问题具有类似的问题(涉及数字而不是数组,但原则相同)。我将逻辑切换为使用
shareReplay
,因为它更具语义,更不容易出错。使用原始主题进行状态管理通常被认为是一种反模式,因为通常情况下,您最终会发现状态泄漏。操作符倾向于管理他们自己的生命周期。好的,谢谢,对于我的用例来说,它看起来相当复杂,所以我最终使用了我在问题中的代码片段中的内容。有没有相反的指示?我应该先仔细检查一下
,我可能有另一个在我的真实代码中阻止了它。关于你的回答,我看到了一个问题和一个问题。问题是_pipeline$是我们订阅的,但它假设我们只添加了过滤器。而在我的情况下,我会删除/添加。问题是您是否使用了
shareReplay(1)
而不是在顶部使用
BehaviorSubject
,以避免订阅时的额外计算?对于您提到的问题,我建议您看看另一个SO问题,该问题具有类似的问题(涉及数字而不是数组,但原则相同)。我将逻辑切换为使用
shareReplay
,因为它更具语义,更不容易出错。使用原始主题进行状态管理通常被认为是一种反模式,因为通常情况下,您最终会发现状态泄漏。操作符倾向于管理他们自己的生命周期。好的,谢谢,对于我的用例来说,它看起来相当复杂,所以我最终使用了我在问题中的代码片段中的内容。有没有相反的指示来代替它?