Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/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
Asynchronous RxJS等待第二个可观测值,然后在出现错误时重试原始可观测值-TypeScript/Angular 2_Asynchronous_Typescript_Angular_Rxjs_Observable - Fatal编程技术网

Asynchronous RxJS等待第二个可观测值,然后在出现错误时重试原始可观测值-TypeScript/Angular 2

Asynchronous RxJS等待第二个可观测值,然后在出现错误时重试原始可观测值-TypeScript/Angular 2,asynchronous,typescript,angular,rxjs,observable,Asynchronous,Typescript,Angular,Rxjs,Observable,我是Angular 2、TypeScript和RxJS的新手,我正在创建一个利用Salesforce Ajax工具包连接库的简单应用程序 我试图编写一个处理程序,以便在调用connections库中的方法时捕获令牌何时过期。我已经创建了一个服务,它基本上包装了连接库以使用可观察的对象。例如,如果我们查看插入函数,我已经创建了自己的包装函数: public insert(object: sforce.SObject): Observable<any> { return new

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

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

 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);
  });
}
我基本上希望原始的
insert
函数等待
refreshtToken
完成。如果成功,我希望再次重试相同的插入,否则我希望原始的插入可观察调用
observer.error


我已经研究了
retry
retryWhen
,但是在等待
refreshttoken()
函数完成之前,我还没有弄清楚如何实现它。对此问题的任何指导或建议将不胜感激。提前谢谢。

操作员接受一个处理错误和源代码的函数。这意味着,如果捕获到错误,可以在
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);
  });
}

谢谢你的回答@paulpdaniels!你能解释一下tap是做什么的吗
this.loginService.login
返回一个
http.post
。我收到错误
this.loginService.login(…)。tap不是一个函数
tap
对流中的事件执行副作用,同时仍让它们通过。您很可能需要使用
import'rxjs/add/operator/tap'
 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);
  });
}
 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);
      });
}