恢复连接后按时间顺序重试请求
Chronologically retry requests after restoring connection
如何在用户没有 Internet 连接时“堆叠”正在进行的请求并在再次联机后按时间顺序重试?
我不能在拦截器中使用“纯”retryWhen,因为每个 intercept() 调用都不知道其他请求(我想)。
我尝试在离线模式下使用拦截器接收请求,将它们添加到数组(如 Observables,类似 this.offlineRequests.push(next.handle(request))
),最后再次重新订阅它们重新建立连接时。但问题是我的组件没有得到响应。我的意思是请求正在发出,但看起来组件已经得到 error 并且它不在乎,我稍后在某个地方订阅了 next.handle()。
如果我把你的问题说清楚了,你不想存储请求(正如你已经在做的那样),而是让组件等待响应而不是在发生超时错误时出错。
使用行为主题存储最后发出的响应,然后您将观察它以触发组件的状态。
使用这意味着即使您的组件由于超时而出错,当连接恢复时,将重新发送的堆栈将 EACH 操作 BehaviourSubject 的最后状态,从而使用新信息重新渲染组件。
程序上
Information stored in stack not sent > Connection comes back > Stack Items sent 1 by 1 > Each response will set a next(data) to the BehaviorSubject which will be Observed by the Components > Each change in value will be reflected by your Components
我会尝试这样的事情:
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),
)
})
);
}
}
网络-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
数组中的位置重试请求。
如何在用户没有 Internet 连接时“堆叠”正在进行的请求并在再次联机后按时间顺序重试?
我不能在拦截器中使用“纯”retryWhen,因为每个 intercept() 调用都不知道其他请求(我想)。
我尝试在离线模式下使用拦截器接收请求,将它们添加到数组(如 Observables,类似 this.offlineRequests.push(next.handle(request))
),最后再次重新订阅它们重新建立连接时。但问题是我的组件没有得到响应。我的意思是请求正在发出,但看起来组件已经得到 error 并且它不在乎,我稍后在某个地方订阅了 next.handle()。
如果我把你的问题说清楚了,你不想存储请求(正如你已经在做的那样),而是让组件等待响应而不是在发生超时错误时出错。
使用行为主题存储最后发出的响应,然后您将观察它以触发组件的状态。 使用这意味着即使您的组件由于超时而出错,当连接恢复时,将重新发送的堆栈将 EACH 操作 BehaviourSubject 的最后状态,从而使用新信息重新渲染组件。
程序上
Information stored in stack not sent > Connection comes back > Stack Items sent 1 by 1 > Each response will set a next(data) to the BehaviorSubject which will be Observed by the Components > Each change in value will be reflected by your Components
我会尝试这样的事情:
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),
)
})
);
}
}
网络-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
数组中的位置重试请求。