【问题标题】:RxJs Observable - Handle 404 by emitting default valueRxJs Observable - 通过发出默认值来处理 404
【发布时间】:2017-08-02 17:10:19
【问题描述】:

我正在调用 MS Graph 来获取用户的照片:

    // lets get the photo itself
    let photo$ = this.graph.get$(`users/${id}/photo/$value`, ResponseContentType.Blob)
        .map(resp => {
            return new Blob([resp.blob()], { type: resp.headers.get['Content-Type']}); })
        .map(photo => {
            let urlCreator = window.URL;
            return this.sanitizer
                .bypassSecurityTrustUrl(urlCreator.createObjectURL(photo));
        })
        .catch(function (e) {
            if(e.status === 404) {
                // no photo for this user!
                console.log(`No photo for user ${id}!  Returning default...`);
                return undefined;
            }
        })
        .toPromise();

但是,许多用户没有照片。在这种情况下,我想做的是为一些默认照片(可能是these 之一)创建一个对象 URL,并从 Observable 发出它。或者甚至只是从 Observable 发出一个undefined,我可以通过显示一些默认图像在前端处理它。

我知道我的 catch 正在触发,因为我在浏览器控制台中看到了这个:

没有用户 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 的照片!返回 默认...(输出已编辑)

我实际上为每个用户提取了许多不同的数据位,每个用户都在自己的 Observable 中。然后我将每个 Observable 转换为 Promises,然后对所有这些执行 Promise.all()。

    // let's pull all of this together to form a ConcreteUser
    return Promise.all([photo$, ...])
        .then(values => {
            const photo = values[0];
            ...

问题是在用户照片出现 404 的情况下,整个 Promise.all 中止,我无法检索用户。

我尝试在 photo$ observable 中捕获错误并发出 undefined(我计划稍后处理),但它似乎并没有达到我想要的效果。

如何在我的 Observable 中处理 404,并发出其他内容(可能是 undefined)而不是杀死 observable?

【问题讨论】:

    标签: angular typescript rxjs observable


    【解决方案1】:

    我想我可能已经想通了。浏览器控制台中潜伏着一个提示......

    TypeError:您在预期流的位置提供了“未定义”。你 可以提供 Observable、Promise、Array 或 Iterable。

    阅读 RxJs documentation on error handling 表明他们正在做我想做的事情,所以我对此有点困惑。但后来我注意到,在文档中他们调用了一个神秘函数getCachedVersion(),我假设它返回了一个实际缓存的东西。但是,如果他们改为返回 Observable.of() 一些实际缓存的东西,那么这可能会解释它。

    当我将捕获代码更改为:

            .catch(function (e) {
                if(e.status === 404) {
                    // no photo for this user!
                    console.log(`No photo for user ${id}!  Returning default...`);
                    return Observable.of(undefined);
                }
            })
    

    ...一切都开始了。

    【讨论】:

      【解决方案2】:

      要将Johns answer 转换为最新的 rxjs 实现,现在如下所示:

      import { Observable, throwError, of } from 'rxjs';
      import { catchError } from 'rxjs/operators';
       
      const observale: Observable<unknown>; 
      
      observale.pipe(
         catchError(err => {
             if(err.error.statusCode === 404) {
                return of(undefined);
             } else {
                //important to use the rxjs error here not the standard one
                return throwError(err);
             }
         })
      )
      .subscribe(val => {
            console.log('success but may be undefined');
         }, err => {
            console.log('error');
      });
      

      【讨论】:

        猜你喜欢
        • 2018-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-05
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        • 2020-04-25
        相关资源
        最近更新 更多