Rxjs?中處理錯(cuò)誤和抓取錯(cuò)誤的代碼案例
使用 Rxjs,對(duì)于初學(xué)者來說,當(dāng)我們處理 observables 錯(cuò)誤的時(shí)候容易疑惑,因?yàn)槲覀儠?huì)考慮使用 try-catch 方式捕獲。但是,Rxjs 是通過操作符來管理錯(cuò)誤。
我們通過代碼案例一步步來了解。案例是使用 angular httpClient 模塊來講解,當(dāng)然這適用于任何數(shù)據(jù)流。
場景
我們的應(yīng)用中使用了一個(gè)服務(wù),用來獲取啤酒列表數(shù)據(jù),然后將它們的第一個(gè)數(shù)據(jù)作為標(biāo)題展示。
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);
}
}應(yīng)用的組件訂閱了它,展示啤酒列表,然后獲取其第一條數(shù)據(jù)。
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 錯(cuò)誤了會(huì)發(fā)生什么呢?我們將該 URL 改成一個(gè)錯(cuò)誤的 URL,通過某種策略來捕獲錯(cuò)誤。
使用 try-catch
在 Javascript 中,我們使用 try-catch 來驗(yàn)證代碼片段,如果某些片段出錯(cuò)了,我們就會(huì)捕獲到它。
但是,在 rxjs 中,try-catch 沒用效果。因?yàn)殄e(cuò)誤是發(fā)生在訂閱范圍(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';
}
}
}訂閱中誰抓取錯(cuò)誤
理解 try-catch 為什么不起作用,記住,當(dāng)我們訂閱第一個(gè) observable 的時(shí)候,訂閱會(huì)調(diào)起三個(gè)可選的參數(shù)。
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:數(shù)據(jù)流被成功捕獲調(diào)用error:發(fā)送一個(gè)Javascript錯(cuò)誤或者異常complete當(dāng)數(shù)據(jù)流完成時(shí)候調(diào)用
所以,錯(cuò)誤是發(fā)生在訂閱函數(shù)的區(qū)域,所以我們?cè)趺闯隽四兀?/p>
使用 Rxjs 的操作符
Rxjs 提供了一些操作符幫助我們處理這些錯(cuò)誤,每個(gè)都可以使用在這些場景中,我們來了解下。
我們將接觸 catchError,throwError 和 EMPTY。
catchError
catchError 抓取錯(cuò)誤,但是會(huì)發(fā)出值。簡而言之,它在錯(cuò)誤的基礎(chǔ)上返回另一個(gè) observable。
我移除上面提到的三個(gè)回調(diào)函數(shù)的策略,然后配合管道來使用 catchError 操作符。
更多相關(guān) pipe
this.beerService
.getBeers()
.pipe(catchError(() => of([{ name: 'my default beer' }])))
.subscribe((beers) => {
console.log(beers);
this.beers = beers;
this.title = beers[0].name;
});如果我們的代碼中錯(cuò)誤時(shí)候需要調(diào)用其他內(nèi)容,
catchError非常適合發(fā)出默認(rèn)值,并且訂閱可以將默認(rèn)值拋出去。
throwError
有時(shí)候,我們不想拋出錯(cuò)誤,但是想要提示錯(cuò)誤信息。針對(duì)這個(gè)場景,throwError 很適合我們。
throwError 不會(huì)觸發(fā)數(shù)據(jù)到 next 函數(shù),這使用訂閱者回調(diào)的錯(cuò)誤。我們我們想捕獲自定義的錯(cuò)誤或者后端提示的錯(cuò)誤,我們可以使用訂閱者中的 error 回調(diào)函數(shù)。
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);
},
});
}更多相關(guān) throwError
EMPTY
有時(shí)候,我們不想在組件中傳播錯(cuò)誤。Rxjs 提供了 EMPTY 常量并返回一個(gè)空的 Observable,并未拋出任何的數(shù)據(jù)到訂閱著回調(diào)中。
this.beerService
.getBeers()
.pipe(
catchError(() => {
return EMPTY;
})
)
.subscribe({
next: (beers) => {
this.beers = beers;
this.title = beers[0].name;
},
error: (err) => console.log(err),
});更多相關(guān) EMPTY
總結(jié)
本文,我們學(xué)習(xí)了如何使用 catchError 在數(shù)據(jù)流中抓取錯(cuò)誤,怎么去修改和返回 observable,或者使用 EMPTY 不去觸發(fā)組件中的錯(cuò)誤。
本文是譯文,采用意譯的形式。原文地址這里
到此這篇關(guān)于Rxjs 中怎么處理和抓取錯(cuò)誤的文章就介紹到這了,更多相關(guān)Rxjs 錯(cuò)誤處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談Vue3.0之前你必須知道的TypeScript實(shí)戰(zhàn)技巧
這篇文章主要介紹了淺談Vue3.0之前你必須知道的TypeScript實(shí)戰(zhàn)技巧,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
由document.body和document.documentElement想到的
不知道大家對(duì)這個(gè)標(biāo)題有沒有想法,反正此前我一直把他們混為了一談。其實(shí)不然,首先需有個(gè)“標(biāo)準(zhǔn)”的概念。2009-04-04
JS監(jiān)聽dom高度變化幾種常用方法總結(jié)
我們?cè)陂_發(fā)中會(huì)遇到一些需求,需要監(jiān)聽元素變化,比如元素屬性變化,元素大小變化,這篇文章主要給大家介紹了關(guān)于JS監(jiān)聽dom高度變化幾種常用方法的相關(guān)資料,需要的朋友可以參考下2023-10-10
JS圖片預(yù)加載 JS實(shí)現(xiàn)圖片預(yù)加載應(yīng)用
由于圖片加載慢,導(dǎo)致用戶體驗(yàn)特別差,本文將介紹一種圖片預(yù)加載技術(shù),需要了解的朋友可以參考下2012-12-12
解決JS表單驗(yàn)證只有第一個(gè)IF起作用的問題
這篇文章主要介紹了解決JS表單驗(yàn)證只有第一個(gè)IF起作用的問題,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12
微信小程序?qū)崿F(xiàn)導(dǎo)航欄選項(xiàng)卡效果
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)導(dǎo)航欄選項(xiàng)卡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02

