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