Zamanlayıcıda catchError'a nasıl devam edilir (rxjs)

Aug 23 2020

Bir zamanlayıcı kullanarak her x saniyede bir httpClient.get yürütmekten sorumlu bir hizmetim var. Hizmet her açıldığında çalışmaya başlamak için bu zamanlayıcıya ihtiyacım var, böylece zamanlayıcı hizmet kurucusunda tanımlanır . Anladığım kadarıyla abonelik aşağıda görüldüğü gibi zamanlayıcı kapsamına kaydedilmelidir (Gerekmiyorsa, yanlış olmadıkça değiştirmek istemiyorum).

Tüm sistem, arka uç sunucusunda hata \ istisnalar \ hata 500 istisnası olmadığı sürece sorunsuz çalışıyor. Şimdi 2 şeye ihtiyacım var:

  1. Arka uç sunucusunda bir sorun olduğunda , Hatayı yakalamak istiyorum .
  2. Bir istisna olsa bile gözlemcinin zamanlayıcı sürelerine göre (bir sonraki tıklamaya kadar) koşmaya devam etmesini istiyorum. Nihai sonucum, bir istisna olduğunda bileşendeki popUpAlert'e ulaşıyor olmalı Koduma bakın - bu webapi denetleyicisi:
public IActionResult getSomeErrorAsTest()
{
    try
    {
        throw new Exception("Serer error");
    }
    catch(Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError, new List<string>());
        //throw ex;
    }
}

Bu hizmettir (verilerin her alma isteğinde değiştiğini varsayın - gerçekten değişiyorsa uygulamaya gerek yoktur):

export class MyService
{
    MyDataSubject = new Subject<any[]>();
    MyDataChanged :Observable>any[]> = this.MyDataSubject.asObservable();
    
    subscribe :Subscription;
    constructor(private httpClient : HttpClient)
    {
        this.subscribe = timer(0, 30000).pipe(
        switchMap(()=>
            this.getData())).subscribe();
    }
    getData()
    {
        return this.httpClient.get<any[]>(<controller url>)
        .pipe(
            tap(res =>
            {
                this.MyDataSubject.next(res);
            }),
            catchError(error =>
                {
                    debugger;//I would expect to catch the debugger here, but nothing happens
                    return throwError(error);
                })
            )
    }
}   

Tüketici bileşeni:

export class MyComponent (private mySrv : MyService)
{
    getMyData()
    {
        let sub =this.mySrv.MyDataChanged.subscribe(result => doSomething(),
                                                    error=> popUpAlert());
    }
}

Yanıtlar

2 RafiHenig Aug 23 2020 at 18:42

CatchErroroperatör hatayı işlemeye izin verir, ancak gözlemlenebilirin doğasını değiştirmez - hata, gözlemlenebilir olarak verilen son koşuldur, bu nedenle emisyon duracaktır. CatchErrorgözlemcinin hata geri aramasını ( metasong ) yükseltmek yerine, gerçekleştiğinde arzu değerini yaymaya izin verir .

İç Gözlemlenebilirdeki (yani içerideki switchMap) hataları işlemek isteyebilirsiniz , bu nedenle burada ortaya çıkan hatalar ana akışta kabarcık oluşturmaz, bu şekilde ana akış, aşağıda gösterildiği gibi bir hata oluştuktan sonra devam eder:

  this.subscribe = timer(0, 30000)
    .pipe(
      switchMap(() => this.getData().pipe(catchError(x => of("handle error here"))))
      // catchError(...) don't handle error here
    )
    .subscribe();