Rxjs 重新连接到源并从上次发出的值继续
我试图弄清楚如何在一个暂时的失败后实现重新连接到observable,从最后一个发出的值继续 假设我有以下方法:Rxjs 重新连接到源并从上次发出的值继续,rxjs,rxjs5,Rxjs,Rxjs5,我试图弄清楚如何在一个暂时的失败后实现重新连接到observable,从最后一个发出的值继续 假设我有以下方法: interface MyQuery { fromId: number; toId: number; } interface MyItem { id: number; val: string; } function observeUnstable(query: MyQuery): Observable<MyItem>; 我想组成一个新的observab
interface MyQuery {
fromId: number;
toId: number;
}
interface MyItem {
id: number;
val: string;
}
function observeUnstable(query: MyQuery): Observable<MyItem>;
我想组成一个新的observable,它将包装上面的原始observable,并从先前订阅失败的位置透明地重新订阅
数据类型将是不透明的,因此我希望使重连接逻辑成为通用的,可能作为一个接受高阶选择器函数的运算符:
let startQuery = { fromId: 1, toId: 10 };
let reconnectable = observeUnstable(startQuery)
.lift(new ReconnectOperator<MyItem>((err, lastValue?) => {
if (err instanceof DisconnectedError) {
// This error indicates that we've been disconnected,
// resubscribing from the place we have stopped
let continueQuery = {
fromId: lastValue ? lastValue.id + 1 : startQuery.fromId,
toId: startQuery.toId
};
return observeUnstable(continueQuery);
} else {
// Rethrowing error we don't expect
throw err;
}
}));
让startQuery={fromId:1,toId:10};
让可重新连接=可观测不稳定(startQuery)
.lift(新的重新连接运算符((错误,最后值?)=>{
if(断开连接的错误实例错误){
//此错误表示我们已断开连接,
//从我们停过的地方重新订阅
设continuequaly={
fromId:lastValue?lastValue.id+1:startQuery.fromId,
toId:startQuery.toId
};
返回可观测不稳定(连续性);
}否则{
//我们没有预料到的错误
犯错误;
}
}));
这是我的重新连接订阅者和重新连接订阅者:
class ReconnectOperator<T> implements Operator<T, T> {
constructor(private handler: (err: any, lastValue?: T) => Observable<T>) {
}
call(subscriber: Subscriber<T>, source: any): any {
return source.subscribe(new ReconnectSubscriber(subscriber, this.handler));
}
}
class ReconnectSubscriber<T> extends Subscriber<T> {
private lastValue?: T;
constructor(destination: Subscriber<T>, private handler: (err: any, lastValue?: T) => Observable<T>) {
super(destination);
}
protected _next(value: T) {
this.lastValue = value;
super._next(value);
}
error(err: any) {
if (!this.isStopped) {
let result: Observable<T>;
try {
result = this.handler(err, this.lastValue);
} catch (err2) {
super.error(err2);
return;
}
// TODO: ???
result.subscribe(this._unsubscribeAndRecycle());
// this._unsubscribeAndRecycle();
//this.source.subscribe(result);
//this.add(subscribeToResult(this, result));
}
}
}
类重新构造运算符实现运算符{
构造函数(私有处理程序:(err:any,lastValue?:T)=>可观察){
}
呼叫(订户:订户,来源:任意):任意{
返回source.subscribe(新的重新连接订阅者(订阅者,this.handler));
}
}
类重新连接订阅服务器扩展订阅服务器{
私人最后价值?:T;
构造函数(目标:订户,私有处理程序:(err:any,lastValue?:T)=>可观察){
超级(目的地);
}
受保护_next(值:T){
this.lastValue=值;
super.\u next(值);
}
错误(错误:任何){
如果(!this.isStopped){
结果:可见;
试一试{
结果=this.handler(err,this.lastValue);
}捕获(错误2){
超级错误(err2);
返回;
}
//待办事项:???
结果.订阅(此._unsubscribeAndRecycle());
//这是。_取消订阅和循环();
//this.source.subscribe(结果);
//添加(subscribeToResult(this,result));
}
}
}
此订阅服务器与CatchSubscriber非常相似,唯一的区别是CatchSubscriber在selector方法中返回原始observable,在我的例子中,我想返回最后一个值,以便选择器可以使用它来组成一个全新的observable,而不是重用原始observable
但是我在某种程度上弄乱了重新订阅逻辑,因此,对于少量测试值,结果observable永远不会返回complete,对于大量测试值,它会因堆栈溢出而崩溃
另外,我的想法是实现一个新的操作符,但如果可以在一个方法中实现它,只使用现有操作符的组合,以一种通用的方式,那就更好了:)
不带运算符的替代方法示例:
function observeStable<T, Q>(
query: Q,
continueQueryFunc: (query: Q, lastValue?: T) => Observable<T>
): Observable<T> {
return observeUnstable<T>(query).catch((err, ???) =>
if (err instanceof DisconnectedError) {
let lastValue = ???
let continueQuery = continueQueryFunc(query, lastValue);
return observeUnstable(continueQuery);
} else {
throw err;
}
);
}
功能可观测(
问:问:,
continueQueryFunc:(查询:Q,lastValue?:T)=>可观察
):可见{
返回observeUnstable(查询).catch((错误,??)=>
if(断开连接的错误实例错误){
让lastValue=???
让continueQuery=continueQueryFunc(查询,lastValue);
返回可观测不稳定(连续性);
}否则{
犯错误;
}
);
}
function observeStable<T, Q>(
query: Q,
continueQueryFunc: (query: Q, lastValue?: T) => Observable<T>
): Observable<T> {
return observeUnstable<T>(query).catch((err, ???) =>
if (err instanceof DisconnectedError) {
let lastValue = ???
let continueQuery = continueQueryFunc(query, lastValue);
return observeUnstable(continueQuery);
} else {
throw err;
}
);
}