-
Notifications
You must be signed in to change notification settings - Fork 1
/
retryWhen.js
76 lines (70 loc) · 1.99 KB
/
retryWhen.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const {of, Observable} = require('rxjs');
const {
tap,
retryWhen,
delay,
retry,
mergeMap,
flatMap,
catchError,
take
} = require('rxjs/operators');
const timer = require('rxjs').timer;
const throwError = require('rxjs').throwError;
const genericRetryStrategy = (
{
maxRetryAttempts = 3,
scalingDuration = 1000,
excludedStatusCodes = []
} = {}) => (attempts) => {
return attempts.pipe(
mergeMap((error, i) => {
const retryAttempt = i + 1;
// if maximum number of retries have been met
// or response is a status code we don't wish to retry, throw error
if (
retryAttempt > maxRetryAttempts ||
excludedStatusCodes.find(e => e === error.status)
) {
return throwError(error);
}
console.log(
`Attempt ${retryAttempt}: retrying in ${retryAttempt *
scalingDuration}ms`
);
// retry after 1s, 2s, etc...
return timer(retryAttempt * scalingDuration);
}),
);
};
let cnt = 0;
function api() {
return new Observable(subscriber => {
console.log('calling api');
cnt++;
setTimeout(() => {
if (cnt > 3) {
subscriber.next('success');
} else {
subscriber.error('fail');
}
}, 400);
});
}
// const retryCount = 2;
api().pipe(
// retryWhen(genericRetryStrategy()),
// retry(5),
// retryWhen(errors => errors.pipe(
// flatMap((err, cnt) => cnt >= retryCount ? throwError(err) : timer(2000))
// )),
retryWhen(errors => errors.pipe(
flatMap((errMessage, cnt) => {
return timer((cnt+1) * 1000);
}),
take(5) // max attempts
))
).subscribe({
next : console.log,
error: errorStatus => console.log('Error: ' + errorStatus)
});