我是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
。
我已经查看了retry
和retryWhen
,但是我还没有弄清楚如何实现它以等待refreshToken()
功能完成。任何关于此事的指导或建议将不胜感激。提前谢谢。
答案 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);
});
}