Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rxjs 重新连接到源并从上次发出的值继续_Rxjs_Rxjs5 - Fatal编程技术网

Rxjs 重新连接到源并从上次发出的值继续

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

我试图弄清楚如何在一个暂时的失败后实现重新连接到observable,从最后一个发出的值继续

假设我有以下方法:

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;
    }
  );
}