如何解决在Angular应用中重试请求多次
在这种情况下,我需要提出获取请求。我确实知道如何使用Angular的http客户端,但是如果请求失败,我需要自动进行多次重试,然后再放弃并引发错误,并且每次重试之间都需要延迟。 >
例如,我需要我的请求(如果失败)总共重试5次,每次重试之间有10秒的延迟。
是否有一种简单明了的方法来做类似的事情?
解决方法
我的角度应用程序也有同样的需求,所以我创建了一个名为retryWithBackoff的可管道运算符。它使用指数补偿,因此重试之间的时间如下:
delayMs * Math.pow(2,retries)
它可以非常简单地使用:
getDiscussionList(): Observable<DiscussionListModel[]> | Observable<never> {
return this.httpClient
.get<DiscussionListModel[]>('/api/discussions').pipe(
retryWithBackoff()
);
这里是操作员:
export function retryWithBackoff<T>(
delayMs: number = 1000,maxRetries: number = 5,maxTime: number = 12000
): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) => {
const currentMs = new Date().getTime();
return source.pipe(
timeout(maxTime),retryWhen(errors => {
let retries = 0;
return errors.pipe(
mergeMap(next => {
// If we caught TimeoutError we must rethrow because retryWhen would retry
// if request failed due to timeout.
// The timeout(maxTime) isn't reached because a new request is sent
// therefore we have to compare against currentMs
if ((next instanceof TimeoutError)
|| (new Date()).getTime() >= currentMs + maxTime) {
return throwError(new HttpTimeoutError());
}
retries++;
if (retries >= maxRetries) {
return throwError(new HttpMaxRetriesError());
}
return timer(delayMs * Math.pow(2,retries));
}),);
})
);
};
}
无论尝试多少次,它都会在12秒后超时。它可以抛出的两个异常只是一个空的自定义异常类:
export class HttpEstablishError {}
export class HttpMaxRetriesError extends HttpEstablishError {}
export class HttpTimeoutError extends HttpEstablishError {}
我也有一些不完整的茉莉花测试:
describe('Utilities',() => {
describe('retryWithBackoff should',() => {
it('return success observable after failing max-1 times',(done) => {
const source = (count,maxRetries) => {
return defer(() => {
if (count <= maxRetries) {
count++;
return throwError(true);
} else {
return of(true);
}
});
};
source(1,5 - 1).pipe(retryWithBackoff(1,5)).subscribe(
(value) => {
expect(value).toBe(true);
},() => {
fail();
done();
},() => {
done();
}
);
});
it('raise HttpTimeoutError if maxTime is reached',(done) => {
const maxTime = 1000;
const source = new Subject<any>();
source.pipe(retryWithBackoff(1000,5,maxTime)).subscribe(
() => {
fail('should not happen');
},(err) => {
expect(err).toBeInstanceOf(HttpTimeoutError);
done();
}
);
});
});
it('raise HttpMaxRetriesError is maxRetries is reached',(done) => {
const source = (count,maxRetries) => {
return defer(() => {
if (count <= maxRetries) {
count++;
return throwError(true);
} else {
return of(true);
}
});
};
source(1,5 + 1).pipe(retryWithBackoff(1,5)).subscribe(
() => {
},(err) => {
expect(err).toBeInstanceOf(HttpMaxRetriesError);
done();
},);
});
});
,
在角度rxj中,有一个名为“ retry(number)”的方法,您可以在(https://angular.io/guide/http)上阅读更多内容:
getConfig() {
return this.http.get<Config>(this.configUrl).pipe(
retry(3),// retry a failed request up to 3 times
catchError(this.handleError) // then handle the error
);}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。