我有一个前端应用程序和一个后端应用程序。前端应用程序要求后端运行后台作业(例如 DELETE/api/v1/object/666
),后端回复 HTTP 202
并给出链接作业(例如 https://.../api/v1/job/13
)。现在前端应用程序必须定期调用此端点,直到作业完成。
我将其实现为递归调用,看起来像这样:
checkAsyncJob(
jobId: string,
interval: number = 2048,
keepTrying: boolean = true,
onFinish: Function
) {
const jobResult
= this.httpClient.get<Job>(this.urlComposer(JOB_BY_UID, jobId));
jobResult.subscribe((job: Job) => {
if (job.finished === null) {
if (keepTrying) {
// TODO: consider getting rid of recursion, it might should be a loop
new Promise(
resolve => setTimeout(resolve, interval)
).then(
() => this.checkAsyncJob(jobId, interval, keepTrying, onFinish)
);
}
} else {
onFinish();
}
});
}
我想在这里避免递归,因为它(我认为)会使浏览器消耗越来越多的内存,直到工作完成。考虑到 httpClient.get()
返回一个可订阅的对象并且主流程不等待其完成,有没有办法将其重新实现为循环?
谢谢!
最佳答案
也许 RxJS 的 retryWhen
可以解决你的问题。它可能是这样的
this.httpClient.get<Job>(this.urlComposer(JOB_BY_UID, jobId))
.pipe(
map((job: Job) => {
if (job.finished === null) {
throw job; // throw as an error so can be catched by retryWhen
}
return job;
}),
retryWhen(errors => {
errors.pipe(
// timer is a RxJS function
delayWhen(() => timer(interval)) // restart again after interval
)
})
)
.subscribe(onFinish);
引用:
- https://www.learnrxjs.io/learn-rxjs/operators/error_handling/retrywhen
- https://www.learnrxjs.io/learn-rxjs/operators/creation/timer
希望对你有帮助
关于javascript - TypeScript - 一次又一次调用 API 端点,直到得到所需的结果 - 递归还是循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60129669/