You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中Map/Catch返回相同值却触发流类型错误的问题求助

Angular中catch分支返回普通对象导致的Stream错误分析

先来看你写的这段代码:

let currentTime:number = (new Date()).getTime(); 
return this.authenticationService.login(credential)
  .map(data => { 
    const token = data.token; 
    const id = data.id; 
    sessionStorage.setItem('userData', JSON.stringify({currentTime, token, id})); 
    return JSON.parse(sessionStorage.getItem('userData')); 
  })
  .catch(error => { 
    sessionStorage.setItem('userData', JSON.stringify({currentTime, error})); 
    return JSON.parse(sessionStorage.getItem('userData')); 
  }); 

你提到map分支的return完全正常,但catch分支一执行就触发了这个错误:

core.js:1598 ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

错误原因

这其实是RxJS操作符的设计差异导致的:

  • map是值转换操作符:它的作用是把流里的每个值转换成另一个值,你可以返回任意普通类型的数据(对象、字符串、数字等),RxJS会自动把这个值包装成一个新的Observable,继续往下传递给订阅者;
  • catch是错误恢复操作符:它的职责是捕获流中的错误,然后返回一个合法的流对象——这个对象必须是Observable、Promise、数组或者可迭代对象中的一种。你现在直接返回了解析后的userData普通对象,不符合catch的要求,所以RxJS就抛出了这个错误。

解决方案

只需要把catch里返回的对象包装成一个Observable就行,根据你用的RxJS版本不同,写法略有区别:

RxJS 5.x(对应Angular 5及更早版本)

// 先导入Observable
import { Observable } from 'rxjs';

// ...

.catch(error => { 
  sessionStorage.setItem('userData', JSON.stringify({currentTime, error})); 
  const userData = JSON.parse(sessionStorage.getItem('userData'));
  return Observable.of(userData); // 把普通对象包装成Observable
}); 

RxJS 6+(Angular 6及以后版本,推荐pipe写法)

// 先导入需要的操作符
import { of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

// ...

let currentTime:number = (new Date()).getTime(); 
return this.authenticationService.login(credential).pipe(
  map(data => { 
    const token = data.token; 
    const id = data.id; 
    sessionStorage.setItem('userData', JSON.stringify({currentTime, token, id})); 
    return JSON.parse(sessionStorage.getItem('userData')); 
  }),
  catchError(error => { 
    sessionStorage.setItem('userData', JSON.stringify({currentTime, error})); 
    const userData = JSON.parse(sessionStorage.getItem('userData'));
    return of(userData); // 用of()包装成Observable
  })
); 

这样修改后,catch分支就返回了一个合法的Observable流,订阅者就能正常接收值,不会再触发那个错误了。

内容的提问来源于stack exchange,提问作者olegario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:48:11