gpt4 book ai didi

javascript - 如何捕获请求错误,然后打开模态,然后在模态关闭时使用 RxJS 重试

转载 作者:数据小太阳 更新时间:2023-10-29 04:11:21 24 4
gpt4 key购买 nike

我想调用一个可以使用 Angular2 的 HTTP 类返回授权失败 (401) 的服务器。

请求的流程应该是这样的:

  • 用户使用 myService.getSomething().subscribe() 向服务器发出请求
  • 如果服务器返回 401:打开一个模态窗口,询问用户的凭据。
  • 用户成功登录回应用
  • 模态框关闭并执行回调
  • 回调应该重试初始请求 (myService.getSomething().subscribe())

这是我目前拥有的:

export class MyService {
// ...
public getSomething(): Observable<Response> {
return this.http.get(url, options).catch((res: any, ob: any) => this.errorHandler(res, ob));
}

public errorHandler(res: Response, ob: Observable<any>): Observable<Response> {
if (res.status === 401) {
this.modalService.open(new ModalConfig({
content: LoginModalComponent,
close: () => { ob.retry(1); console.log("weow") } // <=close is the callback that should initiate the retry action on the initial request.
}));
}
else {
return Observable.throw(res.json());
}
}
}

doSomething() 的用法如下:doSomething().map((r) => r.json()).subscribe((r) => ....)

更新 1

我修改了我的代码,使其看起来像@Thierry Templier 的解决方案。

private errorHandler(res: Response, ob: Observable<any>): Observable<Response> {
if (res.status === 401) {
let closedSubject = new Subject();
this.modalService.open(new ModalConfig({
content: LoginModalComponent,
close: () => { closedSubject.next(res);} // I also tried .complete(), .next(null), .next(true), .next(false)
}));
return ob.retryWhen(() => closedSubject);
}
else {
return Observable.throw(res.json());
}
}

遗憾的是它仍然不起作用。 retryWhen 立即执行,不会等待 closedSubject.next() 被调用。因此它开始一个无限循环,向原始 Observable(getSomething() 函数)发送垃圾邮件。

更新 2

我创建了一个 plunker 来演示无限循环:

https://plnkr.co/edit/8SzmZlRHvi00OIdA7Bga

警告:运行 plunker 将使用字符串 'test' 向您的控制台发送垃圾邮件

更新 3

按照 Thierry 的正确答案,我试图找到一种不使用源字段的方法,因为它是 protected 。在 rxjs 的问题跟踪器上询问是否公开该字段后,一位贡献者回复了一个更好的解决方案。

public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return super.get(url, options).retryWhen((errors: any) => this.errorHandler(errors));
}
private errorHandler(errors): any {
return errors.switchMap((err) => {
if (err.status === 401) {
let closedSubject = new Subject();
this.modalService.open(new ModalConfig({
content: LoginModalComponent,
close: () => { closedSubject.next(err); }
}));
return <any>closedSubject;
}
else {
return Observable.throw(err.json());
}
});
}

我避免使用 .catch,所以我不必使用源字段。

最佳答案

我认为即使在出现 401 错误的情况下,您也需要返回可观察到的内容:

public errorHandler(res: Response, ob: Observable<any>): Observable<Response> {
if (res.status === 401) {
let closedSubject = new Subject();
this.modalService.open(new ModalConfig({
content: LoginModalComponent,
close: () => {
closedSubject.next();
}));
return ob.retryWhen(() => closedSubject);
}
else {
return Observable.throw(res.json());
}
}

有关更多详细信息,请参阅本文:https://jaxenter.com/reactive-programming-http-and-angular-2-124560.html

编辑

问题是 catch 回调的第二个参数不是可观察的源。此源可观察对象对应于其 source 属性的值:

return ob.source.retryWhen((errors) => closedSubject);

查看工作插件:https://plnkr.co/edit/eb2UdF9PSMhf4Dau2hqe?p=preview

关于javascript - 如何捕获请求错误,然后打开模态,然后在模态关闭时使用 RxJS 重试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36654920/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com