Rxjs 中处理错误和抓取错误的代码案例
作者:Jimmy 发布时间:2024-06-23 05:57:38
使用 Rxjs
,对于初学者来说,当我们处理 observables
错误的时候容易疑惑,因为我们会考虑使用 try-catch
方式捕获。但是,Rxjs
是通过操作符来管理错误。
我们通过代码案例一步步来了解。案例是使用 angular httpClient
模块来讲解,当然这适用于任何数据流。
场景
我们的应用中使用了一个服务,用来获取啤酒列表数据,然后将它们的第一个数据作为标题展示。
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable()
export class BeerService {
private apiUrl = 'https://api.punkapi.com/v2/beers';
constructor(private http: HttpClient) {}
getBeers(): Observable<any> {
return this.http.get(this.apiUrl);
}
}
应用的组件订阅了它,展示啤酒列表,然后获取其第一条数据。
import { Component, OnInit } from '@angular/core';
import { BeerService } from './beer.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
title = 'my first beer';
beers = [];
constructor(private beerService: BeerService) {}
ngOnInit() {
try {
this.beerService.getBeers().subscribe((beers) => {
console.log(beers);
this.beers = beers;
this.title = beers[0].name;
});
} catch (err) {
this.title = 'Ups a error';
}
}
}
如果 API
错误了会发生什么呢?我们将该 URL
改成一个错误的 URL
,通过某种策略来捕获错误。
使用 try-catch
在 Javascript
中,我们使用 try-catch 来验证代码片段,如果某些片段出错了,我们就会捕获到它。
但是,在 rxjs
中,try-catch
没用效果。因为错误是发生在订阅范围(subscribe scope),所以 try-catch
解决不了什么,我们需要使用 Rxjs
操作符。
export class AppComponent implements OnInit {
title = 'my first beer';
beers = [];
constructor(private beerService: BeerService) {}
ngOnInit() {
try {
this.beerService.getBeers().subscribe((beers) => {
console.log(beers);
this.beers = beers;
this.title = beers[0].name;
});
} catch (err) {
this.title = 'Us a error';
}
}
}
订阅中谁抓取错误
理解 try-catch
为什么不起作用,记住,当我们订阅第一个 observable
的时候,订阅会调起三个可选的参数。
this.beerService
.getBeers()
.subscribe({
next: (beers) => {
console.log(beers);
this.beers = beers;
this.title = beers[0].name;
},
error: (e) => {
console.log(e);
this.title = 'ups';
},
complete: () => console.log('done'),
});
next
:数据流被成功捕获调用error
:发送一个Javascript
错误或者异常complete
当数据流完成时候调用
所以,错误是发生在订阅函数的区域,所以我们怎么出了呢?
使用 Rxjs 的操作符
Rxjs
提供了一些操作符帮助我们处理这些错误,每个都可以使用在这些场景中,我们来了解下。
我们将接触 catchError
,throwError
和 EMPTY
。
catchError
catchError
抓取错误,但是会发出值。简而言之,它在错误的基础上返回另一个 observable
。
我移除上面提到的三个回调函数的策略,然后配合管道来使用 catchError
操作符。
更多相关 pipe
this.beerService
.getBeers()
.pipe(catchError(() => of([{ name: 'my default beer' }])))
.subscribe((beers) => {
console.log(beers);
this.beers = beers;
this.title = beers[0].name;
});
如果我们的代码中错误时候需要调用其他内容,
catchError
非常适合发出默认值,并且订阅可以将默认值抛出去。
throwError
有时候,我们不想抛出错误,但是想要提示错误信息。针对这个场景,throwError
很适合我们。
throwError
不会触发数据到 next
函数,这使用订阅者回调的错误。我们我们想捕获自定义的错误或者后端提示的错误,我们可以使用订阅者中的 error
回调函数。
ngOnInit() {
this.beerService
.getBeers()
.pipe(
catchError(() => {
return throwError(() => new Error('ups sommething happend'));
})
)
.subscribe({
next: (beers) => {
console.log(beers);
this.beers = beers;
this.title = beers[0].name;
},
error: (err) => {
console.log(err);
},
});
}
更多相关 throwError
EMPTY
有时候,我们不想在组件中传播错误。Rxjs
提供了 EMPTY
常量并返回一个空的 Observable
,并未抛出任何的数据到订阅着回调中。
this.beerService
.getBeers()
.pipe(
catchError(() => {
return EMPTY;
})
)
.subscribe({
next: (beers) => {
this.beers = beers;
this.title = beers[0].name;
},
error: (err) => console.log(err),
});
更多相关 EMPTY
总结
本文,我们学习了如何使用 catchError
在数据流中抓取错误,怎么去修改和返回 observable
,或者使用 EMPTY
不去触发组件中的错误。
本文是译文,采用意译的形式。
来源:https://juejin.cn/post/7133227853184761864
猜你喜欢
- 本文为大家分享了网易2016研发工程师编程题,供大家参考,具体内容如下'''[编程题] 奖学金时间限制:1秒空间限制
- 查看系统原有Python注:可以将python指向python3,但必须修改一些命令如yum的配置,不然会报错。安装依赖yum instal
- 目录prometheus通过exporter监控mysql,并用grafana图表展示1、测试机器 2、配置mysql host0
- 之前折磨了很久,想在Mysql命令行下导出数据库,但就是每天提示不那个错误,后来才知道其实mysqldump不是mysql命令,因此不能在M
- 微信跳一跳自动代码,具体内容如下那个跳一跳python“ * ”,有几个python文件,其中有一个是得到截图,然后鼠标在图片上点击两次,py
- 举例如下:<HTML> <HEAD>  
- 这是不久前写的一个分页存储过程,可应用于SQL Server 2005上面: if object_ID('[proc_SelectF
- 环境 django 1.10.6缘起今天接到一个任务——解决终端满屏日志中的无用错误。 django 会尽可能给你准确报出错误位置,但是一些
- 部署 Jenkins请提前在 Linux 上安装 Docker,在 Linux 中,我们使用 Docker 启动 Jenkins,这样可以避
- 下载mysql安装包,我的是下载mysql-8.0.11-winx64,解压到你想安装的目录下,然后配置环境(window环境下,mac本还
- 基于python+OpenCV的车牌号码识别,供大家参考,具体内容如下车牌识别行业已具备一定的市场规模,在电子警察、公路卡口、停车场、商业管
- 本文实例讲述了Python实现的求解最大公约数算法。分享给大家供大家参考,具体如下:使用Python求解两个数的最大公约数的时候用到了前面介
- 本文实例为大家分享了python实现学生信息管理系统的具体代码,含代码注释、增删改查、排序、统计显示学生信息,供大家参考,具体内容如下运行如
- 目录1、基础理论1.1 事务1.2 分布式事务2、分布式事务的解决方案2.1 两阶段提交/XA2.2 SAGA2.3 TCC2.4 本地消息
- 参数说明以官方说明为例,gather()函数需要三个参数,输入input,维度dim,以及索引indexinput必须为Tensor类型di
- 相信用python的同学不少,本人也一直对python情有独钟,毫无疑问python作为一门解释性动态语言没有那些编译型语言高效,但是pyt
- 今天做数据处理时,遇到了从三维数组中批量加入二维数组的需求。其中三维数组在深度学习的特征数据处理时经常会使用到,所以读者有必要对该小知识点做
- 只要把下面代码放到index.asp或者default.asp中,只要在首页代码顶部引用call Check_Wap(),这个也是我的工程中
- 其实我们平时在深度学习中所说的卷积操作,在 opencv 中也可以进行,或者说是类似操作。那么它是什么操作呢?它就是图像的模糊(滤波)处理。
- python中迭代器和iter()函数迭代器为类序列对象提供了一个类序列的接口。python的迭代无缝地支持序列对象,而且它还允许程序员迭代