我打电话给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();
然而,许多用户没有照片。在这种情况下,我想要做的是创建一个默认照片的对象URL(也许是these之一)并从Observable中发出。或者甚至只从Observable发出一个undefined
,我可以通过显示一些默认图像在前端处理。
我知道我的捕获正在解雇,因为我在浏览器控制台中看到了这一点:
没有用户的照片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中处理404s,并发出其他东西(可能是undefined
)而不是杀死observable?
答案 0 :(得分:6)
我想我可能已经弄明白了。浏览器控制台中隐藏着一个提示...
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);
}
})
......一切都开始了。
答案 1 :(得分:0)
现在将Johns answer转换为最新的rxjs实现,如下所示:
import { Observable, throwError, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
const observale: Observable<>;
observale.pipe(
catchError(err => {
if(err.error.status === 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');
});