RxJS дождаться второй наблюдаемой, а затем повторить исходную наблюдаемую ошибку - TypeScript/Angular 2

Я довольно новичок в Angular 2, TypeScript и RxJS, и я создаю простое приложение, которое использует библиотеку соединений Salesforce Ajax Toolkit.

Я пытаюсь написать обработчик для перехвата, когда токен истек каждый раз, когда вызывается метод из библиотеки соединений. Я создал службу, которая по существу оборачивает библиотеку соединений для использования наблюдаемых. Например, если мы посмотрим на функцию вставки, я создал свою собственную функцию-обертку:

 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,

Я смотрел в retry а также retryWhenОднако я не смог выяснить, как реализовать это, чтобы ждать 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);
      });
}
Другие вопросы по тегам