2016-11-21 80 views
0

赶上从BehaviorSubject错误由异步管签约时,我有一个rxjs BehaviorSubject我同意使用async管从角2,我有一个catch来处理它抛出最后的错误。 问题是,每当我得到一个错误,它就会启动一个无限循环,因为我的catch返回从BehaviorSubject派生的Observable,我认为当我返回catch时,async管道重新订阅了可观察值。无限循环对角2

代码看起来大致是这样的:

ListService - 是@Injectable在那里我有BehaviorSubject并与Observable财产。

private listSubject: BehaviorSubject<IItem[]>; 

public get listObservable() { 
    return this.listSubject.asObservable() 
} 

private error(error: IError) { 
    this.listSubject.error(error); 
} 

ListComponent - 是@Component显示列表中观察到。你可以看到,我的catch返回当前可观察对象,因为它必须返回一个可观察对象。所以,发生什么是,当我发送this.listSubject.error(error)代码进入一个无限循环无限期调用catch,因为,就像我之前说过的,我认为BehaviourSubject重新抛出错误,因为async管道重新订阅可观察的catch返回它。

我试图在错误中返回以前的缓存阵列以返回Observable.of(error.cached),但我得到了一组全新的问题,因为认为异步没有订阅BehaviorSubject了。

就像我之前说的,这是我真实代码的粗略表示,但逻辑基本上是这样。

我一直在尝试各种不同的方法,但我无法设法得到这个无限循环停下来。

在此先感谢您的帮助。

+0

抛出错误的类型是什么,以及在错误的情况下,您希望代码执行什么操作? – KwintenP

+0

任何错误,我在List服务中使用该错误函数传递错误,即使我只传递一个字符串,我也会遇到问题。但通常我传递api响应错误。 –

回答

2

这是一个通常不好的主意,手动派遣一个主题上的错误,应该只弹出数据(如你的情况下的BehaviorSubject)。原因是当Subject发生错误时,Subject本质上是已死 - >意思是说没有新数据可以再弹出。这是rxjs的核心概念之一。这里是一个小例子:

let stream$ = new Rx.BehaviorSubject(1); 

stream$.subscribe(x => console.log("Logging: " + x), e => console.error("Error: " + e)); // logs 1, 2, Error: ... 

stream$.next(2); 
stream$.error(new Error("Some error message.")); 
stream$.next(3); // this will have no effect, because the stream is "dead" 
stream$.subscribe(x => console.log("Logging 2: " + x), e => console.error("Error: " + e)); // this will just log the error 

对于你的情况,这意味着你做了一些错误处理,但当时刚刚回归的“老,死的,错误” -subject - 换句话说:传播错误下来流。 (我不是假设handleError()创建一个新鲜Subject,这将是一个可怕的实践反正。)

通常这意味着.error应该仅被用于执行所定义的操作和具有确定的结果的数目的流然后完成或抛出错误,但不在Subject上,您希望在应用程序的整个生命周期内发出数据。

如何解决你的情况:快速&肮脏(真的很脏!)的方式是使用两个单独的主题,一个用于数据,一个用于错误(用.next弹出)。

正确的修复方法:将您的体系结构拆分为数据生成流和数据存储部分。

生命周期会是这个样子:

剖成流量

  1. 某些事件(如按钮,点击,或一些基于时间的事件)
  2. Service.generateOrFetchData()handleErrors。 ()
  3. StoreService.someSubj.next(data) - (步骤3可以是可选的,具体取决于您在步骤2中如何处理错误)

订阅流

  1. UI订阅StoreService.someSubj
  2. UI自动更新,每当新的数据被弹出,没有错误处理所需

完美修复将使用像这样随时可以使用的思维透视存储体系结构,但是在现有项目中实现这一点会带来重大的重构需求。

+0

是的,我现在跟着脏兮兮的修补程序去了,一旦我完成了目前我正在做的事情,我会回到这个。 –