RxJS等待第二个observable然后重试原始observable - TypeScript / Angular 2

时间:2016-07-27 01:10:59

标签: asynchronous typescript angular rxjs observable

我是Angular 2,TypeScript和RxJS的新手,我正在创建一个利用Salesforce Ajax Toolkit连接库的简单应用程序。

我正在尝试编写一个处理程序,以便在调用连接库中的方法时捕获令牌何时到期。我创建了一个服务,它基本上包装连接库以使用observables。例如,如果我们查看插入函数,我已经创建了自己的包装函数:

 public insert(object: sforce.SObject): Observable<any> {
   return new Observable(observer => {
   // successfully inserted the record
   let insertSuccess = (result) => {
     observer.next(result);
     observer.complete();
    }

    // An error occured inserting the record
    let insertError = (result) => {
      // This does not work yet
      if (result.faultcode.indexOf('INVALID_SESSION_ID') != -1) {
        this.refreshToken();
      }
      else {
          observer.error(result);
      }
    }

    let callback = { onSuccess: insertSuccess, onFailure: insertError };
    sforce.connection.create([object], callback);
  });
}

我有另一个刷新访问令牌的功能:

 public refreshToken(): void {
    this.loginService.login().subscribe(
        response => {

            Globals.SESSION_TOKEN = response.access_token;

            //initialize the salesforce connection 
            this.init(Globals.SESSION_TOKEN, this.loginService.AuthParams.SOAP_URL);
        },
        error => {

        }
    );
}

我基本上希望原始的insert函数等待refreshToken完成。如果成功,我想再次重试相同的插入,否则我希望原始插入observable调用observer.error

我已经查看了retryretryWhen,但是我还没有弄清楚如何实现它以等待refreshToken()功能完成。任何关于此事的指导或建议将不胜感激。提前谢谢。

1 个答案:

答案 0 :(得分:1)

catch运算符接受处理错误Observable的函数。这意味着如果您发现错误,您可以确定是否要重新订阅catch块中的原始来源:

 public insert(object: sforce.SObject): Observable<any> {
   return new Observable(observer => {
   // successfully inserted the record
   let insertSuccess = (result) => {
     observer.next(result);
     observer.complete();
    }

    // An error occured inserting the record
    let insertError = (result) => observer.error(result);


    let callback = { onSuccess: insertSuccess, onFailure: insertError };
    sforce.connection.create([object], callback);
  }).catch((err, source) => {
     if (err.faultcode.indexOf('INVALID_SESSION_ID') != -1) {
        //This waits for the refresh to complete and then resubscribes
        //to the source
        //If the refresh errors then it will skip the resubscribe
        return this.refreshToken().flatMapTo(source);
     }
     //Non-authentication error
     return Observable.throw(err);
  });
}

然后将refreshToken函数改为:

 public refreshToken(): Observable<any> {
    return this.loginService.login()
      .tap(response => {
        Globals.SESSION_TOKEN = response.access_token;

        //initialize the salesforce connection 
        this.init(Globals.SESSION_TOKEN, this.loginService.AuthParams.SOAP_URL);
      });
}