2016-07-27 61 views
1

我是Angular 2,TypeScript和RxJS的新手,我正在創建一個利用Salesforce Ajax Toolkit連接庫的簡單應用程序。RxJS等待第二個觀察,然後重試原始觀察錯誤 - TypeScript/Angular 2

我想寫一個處理程序來捕獲當一個標記已經過期任何時候從連接庫中調用一個方法。我創建了一個基本上包裝連接庫以使用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來完成。如果成功,我想再次重試相同的插入,否則我想讓原始插入可觀察來調用observer.error

我查看了retryretryWhen,但是我還沒有弄清楚如何實現它來等待refreshToken()函數完成。任何關於這個問題的指導或建議將不勝感激。先謝謝你。

回答

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

感謝答案@paulpdaniels!你能解釋一下水龍頭的功能嗎? 'this.loginService.login'返回一個'http.post'。我收到錯誤'this.loginService.login(...)。tap不是函數' – ThreadedLemon

+1

'tap'對流中的事件執行副作用,但仍允許它們通過。你很可能必須使用'import'rxjs/add/operator/tap''來包含操作符 – paulpdaniels