gpt4 book ai didi

javascript - 重试对 Angular 中另一个来源的失败 API 调用

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:22:39 24 4
gpt4 key购买 nike

我想实现一个逻辑,如果对当前源的调用失败,则重试对另一个源的 API 调用。我希望它在服务层处理,而不是在每个组件中实现这个逻辑。

比如我在端点服务中有这样的功能

 getAll(): Observable<IssueListItem[]> {
let endpointUrl = `${this.apiConnectionService.getApiUrl()}api/Issues`;
return this.http.get<IssueListItem[]>(endpointUrl, { headers: this.dataService.requestHeaders })
.pipe(retryOtherApi(this.apiConnectionService),
catchError(error => this.handleError(error)));
}

这个函数的消费者看起来像:

ngOnInit() {
this.issuesEndpointService.getAll()
.subscribe(_ => this.issues = _);
}

我希望它对重试逻辑一无所知。

因此,我尝试创建一个运算符“retryOtherApi”,我可以在其中将原点切换到另一个原点。

export function retryOtherApi(apiConnectionService: ApiConnectionService) {
const maxRetry = apiConnectionService.apiOriginsCount;

return (src: Observable<any>) => src.pipe(
retryWhen(_ => {
return interval().pipe(
flatMap(count => {
console.log('switch to: ' + apiConnectionService.getApiUrl())
apiConnectionService.switchToOther();
return count === maxRetry ? throwError("Giving up") : of(count);
})
);
})
);
}

切换有效,但不幸的是,没有调用整个 getAll 函数,它使用相同的旧 URL 重试 n 次。

所以问题是如果当前API不可用,如何实现对其他API逻辑的通用重试。

如果将问题改写为更常见的情况,它就变成了如果当前失败,如何使用其他参数调用 HTTP 端点。

最佳答案

public getAll(): Observable<IssueListItem[]> {
let call = () => {
let endpointUrl = `${this.apiConnectionService.getApiUrl()}api/Issues`;
return this.http.get<IssueListItem[]>(endpointUrl, { headers: this.dataService.requestHeaders })
};

return <Observable<IssueListItem[]>>call()
.pipe(
retryOtherApi(this.apiConnectionService, () => call()),
catchError(error => this.handleError(error))
);
}

这是一个重试运算符:

export function retryOtherApi(apiConnectionService: ApiConnectionService, recall: () => Observable<any>) {
const maxRetry = apiConnectionService.apiOriginsCount;
let count = 0;

let retryLogic = (src: Observable<any>) => src.pipe(
catchError(e => {
if (e.status === 0) {
apiConnectionService.switchToOther();
console.log('switch to: ' + apiConnectionService.getApiUrl())
return count++ === maxRetry ? throwError(e) : retryLogic(recall());
} else {
return throwError(e);
}
}));

return retryLogic;
}

它有效,但是:

  1. 现在我需要为其他线程实现不切换 api 的逻辑同时。
  2. 在 TS 类型转换上有一些问题,即为什么我在返回之前硬编码类型。

关于javascript - 重试对 Angular 中另一个来源的失败 API 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52234943/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com