我会尝试这样的:
offline.interceptor.ts
class OfflineInterceptor implements HttpInterceptor {
constructor (private networkStatusService: NetworkStatusService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError(err => {
// At this point, we must return an observable.
return concat(
// We're first waiting for the connection to become available.
// `ignoreElements` - will ignore `next` notifications. But it will let `error/complelete`
// notifications pass through.
this.networkStatusService.isOnline$.pipe(first(), ignoreElements()),
// After we're back online, we make the request once again.
next.handle(req),
)
})
);
}
}
network-status.service.ts
class NetworkStatusService {
private networkStatus = new Subject<boolean>();
get isOnline$ () {
return this.networkStatus.pipe(
filter(Boolean)
);
}
}
因此,当没有互联网连接时,订阅将处于某种 待定状态,直到连接重新建立。注意concat 的第一个参数:
return concat(
// !
this.networkStatusService.isOnline$.pipe(first()),
next.handle(req),
)
本质上发生的事情是networkStatus Subject 实例将有一个新订阅者。并且由于每次请求因连接不良而失败时都会发生这种情况,因此将尊重新订阅者的顺序。所以,如果我们有这样的东西(按顺序):
// In `Component1` - this fails first.
this.http.get(...);
// In `Component2` - this fails second.
this.http.get(...);
// In `Component3` - this fails third.
this.http.get(...);
networkStatus' 的订阅者将是(大致 - 有更多的事情发生,但这个概念仍然成立):
// networkStatus.subscribers
[
SubscriberThatCorrespondsToComp1Subscriber,
SubscriberThatCorrespondsToComp2Subscriber,
SubscriberThatCorrespondsToComp3Subscriber,
]
这意味着当连接恢复在线时,将根据它们在networkStatus.subscribers 数组中的位置重试请求。