当前位置: 首页
前端开发
Angular中Observable常见问题与解决方法

Angular中Observable常见问题与解决方法

热心网友 时间:2026-06-16
转载

在Angular中,Observable是处理异步操作的核心工具,支持取消订阅、多次发射数据,并通过pipe操作符实现过滤、映射等变换。与Promise相比,其状态可多次改变。单元测试中,通过构造mock数据能测试嵌套Observable的数据流,常用于HTTP请求与事件流。

Angular Observable 完全指南:核心用法与实战技巧

熟悉 Promise 的朋友可能会觉得 Observable 非常相似——两者确实都能处理异步操作。不过 Observable 在功能上更为强大且灵活。下面我们系统梳理一下 Observable 的典型用法与关键特性。

使用之前,先要在对应组件的文件顶部引入相应模块:

import { Observable } from 'rxjs';

假设我们要创建一个发送异步请求的服务文件 storage.service.ts,把它放在 service 层中,任何需要的地方都可以直接注入使用。

Observable 的基本用法与 Promise 类似:先 new 一个实例,实例接收一个函数参数,函数内部实现异步操作;该函数还接收一个 observer 参数,通过 observer.next 将异步数据推送出来,外部通过订阅即可接收。

  // observable 使用之前先引入
  getObservable(){
    return new Observable((observer)=>{
      setTimeout(()=>{
        var data = 'observer数据'
        observer.next(data)                //相当于promise的resolve
      },2000)
    })
  }

然后在 home 组件中调用这个服务。注意:需要先在 home.ts 中引入 storage.service.ts,并在 constructor 里声明注入变量:

import { StorageService } from 'src/app/services/storage.service';
 
constructor(public storage:StorageService) { }

之后便可在 home 组件中订阅 observer.next 抛出的数据:

let oberverData = this.storage.getObservable()
 
let d = oberverData.subscribe((res)=>{        //相当于promise的then
      console.log(res)
})

然而 Observable 相比 Promise 还提供了几个关键增强能力,下面逐一解析。

1、取消订阅:随时终止数据流

Observable 允许在订阅之后随时手动取消订阅,避免不必要的资源占用或内存泄露。

setTimeout(()=>{
      d.unsubscribe()            //一秒钟之后取消订阅,接收不到消息
},1000)

2、多次输出:支持持续推送数据

Promise 的状态一旦从 pending 变为 reject 或 resolve 后就不可再变更,因此无法多次输出同一个 resolve 的值。但 Observable 天然支持多次异步推送。请看对比示例:

let p = new Promise(resolve=>{
      setInterval(()=>{
        resolve('promise interval值')
      },2000)
})
p.then(res=>console.log(res))     //只输出一次
 
// observable
let o = new Observable(observer=>{
    setInterval(()=>{
       observer.next('observable interval值')
    },2000)
})
o.subscribe(res=>console.log(res))    //每隔2秒输出一次

3、使用 pipe 对数据进行变换与过滤

通过 RxJS 的 pipe 操作符,可以对发射的数据进行过滤、映射、组合等复杂处理,实现响应式数据流操作。

let o1 = this.storage.getObservable1()
o1.pipe(
   filter((data:any)=> {
      return data%2 == 0
   }),
   map(value => {
      return value*value
   })
).subscribe(res=>console.log(res))

Angular Observable 数据类型的单元测试 mock 数据准备

假设有一个组件,它的 items 属性是一个嵌套的 Observable:

\

 items$: Observable[]> = this.componentData$.pipe(
    map((data) => data.productCodes.trim().split(' ')),
    map((codes) =>
      codes.map((code) => this.productService.get(code, this.PRODUCT_SCOPE))
    )
  );

ComponentData$ 的类型定义:

  private componentData$: Observable = this.componentData.data$.pipe(
    filter(Boolean)
  );

Model 接口的定义:

\

componentData$ 的类型为 Observable,在 map 的回调中又嵌套了另一个 map 操作,因此最终返回的类型是嵌套的 Observable。

\

由于 items$ 的数据来自 componentData$,而 componentData$ 又源自 componentData,所以只需要构造好 componentData 的模拟数据即可:

  private componentData$: Observable = this.componentData.data$.pipe(
    filter(Boolean)
  );

下面展示如何在单元测试中创建 mock 数据,示例为 MockCmsProductCarouselComponent

\

完整解决方案

const mockComponentData: CmsProductCarouselComponent = {
  uid: '001',
  typeCode: 'ProductCarouselComponent',
  modifiedTime: new Date('2017-12-21T18:15:15+0000'),
  popup: 'false',
  productCodes: productCodeArray.join(' '),
  scroll: 'ALLVISIBLE',
  title: 'Mock Title',
  name: 'Mock Product Carousel',
  container: 'false',
};
const MockCmsProductCarouselComponent = >{
  data$: of(mockComponentData),
};
来源:https://www.jb51.net/article/264499.htm

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
如何用拖放在Flask看板应用中更新数据库状态

如何用拖放在Flask看板应用中更新数据库状态

在Flask看板应用中,通过HTML5拖放API结合前端fetch异步POST请求,将拖拽任务的task_id和target_state发送至后端路由;后端接收JSON后更新数据库并提交事务,实现跨列拖拽时实时更新状态。需注意将事件绑定到容器而非子元素,并在ondragover中阻止默认行为以确保drop触发。

时间:2026-07-09 07:01
如何用CSS :has()选择器快速实现悬停span显示相邻div

如何用CSS :has()选择器快速实现悬停span显示相邻div

利用CSS的:has()伪类选择器,通过` bar:has(> baz:hover)+ qux`实现悬停内联元素时显示相邻块级容器,解决了传统相邻兄弟选择器无法跨层级匹配的局限,可用于悬停图标显示详情框等交互场景。需注意浏览器兼容性和性能优化,避免过度使用影响渲染效率。

时间:2026-07-09 07:01
display:block居中段落文本的响应式实现方法

display:block居中段落文本的响应式实现方法

通过`display:block`与`max-width`限制宽度,配合`margin:auto`使段落块水平居中并实现响应式布局;同时用CSS统一控制段落间距,避免脱离文档流,提升可读性与维护性。

时间:2026-07-09 07:01
JavaScript代码去重:高效避免重复编写的技巧

JavaScript代码去重:高效避免重复编写的技巧

将重复代码中的变化点提取为参数,利用ES6模板字符串动态生成选择器,可消除重复、保持一致性。注意参数安全性,必要时进行白名单校验;批量化场景可扩展为数组形式;现代框架中更推荐数据驱动或组件化封装替代手动选择器。

时间:2026-07-09 07:00
使用容器查询单位cqw实现表单输入框相对于祖父容器百分比宽度

使用容器查询单位cqw实现表单输入框相对于祖父容器百分比宽度

利用CSS容器查询单位cqw,表单输入框宽度可直接基于祖父容器计算,绕过中间包装器尺寸干扰,实现简洁响应式布局,无需硬编码或JavaScript,显著降低维护成本,提升嵌套结构下的布局灵活性。

时间:2026-07-09 07:00
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜