Я пишу приложение для Ionic, используя Ionic 4, и у меня возникают проблемы с выполнением моих Обещаний в правильном порядке (или, возможно, я просто думаю об этом неправильно).Я также впервые использую Typescript, так что терпите меня.
Приложению необходимо взаимодействовать с нашим API, который использует Oauth.Я храню токены Oauth с использованием ионного хранилища, которое также использует Promises для получения / установки, так что это добавляет к моей проблеме.
Если вы берете следующие фрагменты файла:
oauth.service.ts:
export class OauthService {
...
public async setTokens(token: string, token_secret: string) {
return Promise.all([this.storage.set('token', token), this.storage.set('token_secret', token_secret)]);
}
public async getTokens() {
return Promise.all([this.storage.get('token'), this.storage.get('token_secret')]);
}
...
}
api.service.ts:
export class ApiService {
...
public async getCustomer() {
const requestData = {
.. request data ..
};
return this.authorisedRequest(requestData);
}
private authorisedRequest(requestData) {
return this.oauth.getTokens().then(([token, token_secret]) => {
if (!token || !token_secret) {
return Promise.reject('Tokens not available');
}
const tokens = {
'key': token,
'secret': token_secret
};
const oauthHeader = this.oauth.createHeader(requestData, tokens);
const headers = this.createHeaders({
'Authorization': oauthHeader.Authorization
});
return this.apiRequest(requestData.method, requestData.url, {}, headers);
}).catch((error) => {
// @todo what to do here, if anything?
console.info('token error:', error)
});
}
private async apiRequest(type, path, data, headers = null) {
if (!headers) {
headers = this.headers;
}
const response = new Subject();
const httpRequest = new HttpRequest(
type,
path,
data,
{
headers: headers
}
);
this.http.request(httpRequest).subscribe((res: any) => {
if (res.type) {
response.next(res.body);
}
}, error => {
const responseError = error.error.messages.error[0];
this.alerter.presentAlert(responseError.message);
response.error(error);
});
return response;
}
}
authentication.service.ts:
export class AuthenticationService {
...
public checkAuth() {
this.api.getCustomer().then((request: Subject<any>) => {
// this still executes but request is undefined.
request.subscribe((resp: any) => {
this.isLoggedIn = true;
}, (error) => {
this.isLoggedIn = false;
});
});
}
...
}
По большей части это работает нормально,во всех случаях, когда токен существует, так как обещание не отклонено.
Однако, когда я запускаю checkAuth () для init (чтобы проверить, уже вошел ли пользователь), обещание getTokens () возвращает отклонение, котороесразу же перехватывается (в api.service), но внутри checkAuth по-прежнему выполняется 'then', хотя он должен был быть перехвачен, что выдает ошибку:
TypeError: Cannot read property 'subscribe' of undefined
IМожно переместить блок catch внутрь функции checkAuth, но это будет означать, что мне придется делать это во всех случаях, когда я выполняю вызов API (~ 30 нечетных конечных точек), что не идеально.
Без перехватов я получаю эту ошибку:
Uncaught (in promise): Tokens not available
Как я могу либо заставить отказ отклониться молча, либо, возможно, просто передать ошибку по checkAuth?
Или я иду по этому процессу совершенно неправильно?У меня есть ощущение, что мой процесс получения токена oauth здесь неправильный (вызывая вложенные обещания для любого вызова API).