gpt4 book ai didi

Angular rxjs : keep subscription after error reached

转载 作者:行者123 更新时间:2023-12-05 07:22:03 24 4
gpt4 key购买 nike

我需要知道如何在抛出错误后保持订阅。

我创建了这个可观察对象:

let saveClick$ = Observable.fromEvent(this.saveButton.nativeElement, 'click');

所以,我已经尝试使用 Observable.empty,但到目前为止我已经能够弄清楚它发出一个完整的,所以订阅者将被删除:

this.saved$ = saveClick$.pipe(this.pushUser(), catchError(() => Observable.empty<AdministrationUser>()), share());

我希望当出现任何错误时,订阅会被保留。

有什么想法吗?

附加代码:

// Custom pipes
private push = <T>() => switchMap<T, AdministrationUser>(() => this.service.push(this.user));
private handleError = <T>() => catchError<T, Array<{code: string, message: string}>>((error: ResponseError) => Observable.of(error.errors));
private handleEmptyUser = <T>() => catchError<T, AdministrationUser>(() => Observable.of(UsuarisadministracioSubcomponentComponent.EMPTY_USER));

private pushUser = () => pipe( //simplified pipe
this.push()
);

我的服务是:

const buildURL = () => map((filter: {userId: string} & Trace) => this.buildPushURL(filter.currentUser, filter.currentApplication, filter.userId));
const makeRequest = () => switchMap((url: string) => httpMethodFn.call(this.authHttp, url, user));
const buildResponse = () => map(() => user);
const onErrorGetDetails = () => catchError((error: Response) => Observable.throw(<ResponseError>error.json()));

return Observable.of({userId: user.id})
.pipe(
buildURL(),
makeRequest(),
buildResponse(),
onErrorGetDetails()
);

最佳答案

您应该在内部可观察管道而不是源可观察管道中捕获错误。如果您在 source observable 上捕获到错误,那么根据 rxjs 概念,source observable 将不会在错误发生后发出新值。因此,像这样捕获内部可观察对象中的错误:

this.saved$ = saveClick$.pipe(
//i am assuming this.pushUser() is a higher order function which returns an observable
this.pushUser()
.pipe(
catchError(() => Observable.empty<AdministrationUser>())
),
share()
);

在内部 observable 中捕获错误将使您的源 observable 保持事件状态,并且即使您的内部 observable 抛出错误,它也会继续发出值。您可以根据需要移动您的 share() 运算符[即无论是在你的内部可观察到的还是在源可观察到的管道中],但想法保持不变 - 捕获内部可观察到的管道内的错误以保持你的源(外部)可观察到的事件。

编辑 1:[根据用户的最新代码建议简化代码]

请像这样在您的服务中定义您的推送方法:

push(user) {

//By seeing your code; I could not figure out where and how are you passing the parameter in buildUrl
//It appears to me that this.buildPushURL method simply return an URL based on the passed parameters and IT DOES NOT MAKE
//ANY HTTP CALL TO YOUR BACKEND. IF THAT IS TRUE -
//THEN please adjust the below code accordingly as I dont know how you use this method OR PLEASE provide some more detaling
//on this.buildPushURL() method
const url = this.buildPushURL(filter.currentUser, filter.currentApplication, filter.userId);

//I am assuming that httpMethodFn calls http.get() or http.post() and returns an observable
//Suggestion - Why you dont use httpClient.get or httpClient.post() directly? It will avoid to call
//httpMethodFn by httpMethodFn.call?

//Bottom line is - httpMethodFn.call must return an observable otherwise adjust your httpMethodFn.call code to return an observable
//to make below code work.
return httpMethodFn.call(this.authHttp, url, user)
.pipe(
map(user => {
console.log(user);
return user;
}),
catchError(error => throwError(<ResponseError>error.json()))
);

}

然后像这样使用它-

yourMethodReturnsAnObservableWhichIsSubscribeByTheConsumer() {

const saveClick$ = Observable.fromEvent(this.saveButton.nativeElement, 'click');

return saveClick$.pipe(

switchMap(() => {
return this.push(user)
.pipe(
//you catch error here so that your outer observable will keep alive

//please adjust you code as per your need
//I guess it will give you an idea
handleError()
)
})


);
}

希望您对如何简化代码有所了解。我无法提供完美的解决方案,因为我不知道您的设计和完整代码。我很确定上面的代码会给你一个想法。

一个建议——使用高阶函数很好,但要明白不要过度使用它们,因为它会使你的代码有点难以理解[PS——这是我个人的意见,有不同意见是件好事。 .:)]。通过应用函数式编码风格,使您的可观察链尽可能简单。 RXJS 很棒:)

关于 Angular rxjs : keep subscription after error reached,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56650835/

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