iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
自我挑戰組

菜雞也能優雅的征服RxJS系列 第 30

菜雞們一起征服RxJS - day30: 向後台發出請求並即時偵錯: ajax, catchError

  • 分享至 

  • xImage
  •  

ajax

  • 我想大家對ajax應該不陌生,RxJSajax也符合我們過去的使用,這篇文章我們會先介紹使用GET的兩種方式,當然,如果想了解如何使用POST等其他用法,可以參考RxJS官網-ajax或下圖

發出GET的請求: ajax(URL) 及 ajax.getJSON

  • ajax(URL): 取得backend回傳的資料,你可以進一步解析status是否為200,或者responseJSON資料...等。
  • ajax.getJSON(URL):直接解析response回傳的JSON資料

stackblitz

import { ajax } from 'rxjs/ajax';
import { map, catchError, of } from 'rxjs';

const URL = 'https://api.github.com/users?per_page=5';

// 測試1: 使用ajax(URL) 及 ajax.getJSON(URL)觀察取得資料的差異性
const obs$ = ajax(URL).pipe(
  map((userResponse) => console.log('users: ', userResponse)),
);

obs$.subscribe({
  next: (value) => console.log('===>next:', value),
  error: (err) => console.log('===>error:', err),
});

使用catchError來偵測GET是否有異常

case1: 先不加catchError

stackblitz

import { ajax } from 'rxjs/ajax';
import { map, catchError, of } from 'rxjs';

const URL = 'https://api.github.com/users?per_page=5';
const URL404 = 'https://api.github.com/404';

// 測試2: 使用 URL 或 URL404測試 catchError並觀察
const obs$ = ajax
  .getJSON(URL404) //<-- 呼叫URL 404
  .pipe(map((userResponse) => console.log('users: ', userResponse)));

obs$.subscribe({
  next: (value) => console.log('===>next:', value),
  error: (err) => console.log('===>error:', err),
});
  • 我們先建置一個URL404變數,來提供ajax.getJSON呼叫
  • 從印出的結果來看,由於URL404是一個錯誤的網址,obs$.subscribe()內的observer觀察者error會被呼叫。

case2: 加catchError在pipe中攔截

stackblitz

import { ajax } from 'rxjs/ajax';
import { map, catchError, of } from 'rxjs';

const URL = 'https://api.github.com/users?per_page=5';
const URL404 = 'https://api.github.com/404';

// 測試2: 使用 URL 或 URL404測試 catchError並觀察
const obs$ = ajax.getJSON(URL404).pipe(
  map((userResponse) => console.log('users: ', userResponse)),

  // 加入catchError來捕捉 ajax GET過程的錯誤訊息
  catchError((error) => {
    console.log('catchError: ', error);
    return of(error);
  })
);

obs$.subscribe({
  next: (value) => console.log('===>next:', value),
  error: (err) => console.log('===>error:', err),
});

  • 從印出的結果來看,由於中間過程有catchError,也就是說~

錯誤已經在pipe()之中被攔截走了
錯誤已經在pipe()之中被攔截走了
錯誤已經在pipe()之中被攔截走了

因此,observer.next()就會如正常的情況下被呼叫。

我們整理一下catchError測試結果

✍Recap

  • RxJSajax與過去使用ajax的方法一樣。
  • ajax(URL)ajax.getJSON(URL)能夠讓我們快速執行GETAPI。
  • 使用ajax時,於pipe()中搭配catchError,能夠即時攔截error,也因此最後會呼叫observer.next(),若未加入catchError,則會在最後呼叫observer.error()

☕完賽心得

/images/emoticon/emoticon62.gif

  • 喔耶 ~~~ 終於完賽啦!繼上一次的菜雞們,讓我們一起征服JS及React吧到現在已經過了兩年了,因工作的需求,我從React被迫投向Angular的懷抱,也因此認識了RxJS這門技術,順勢成為了我這次參加鐵人賽的主題。

  • 哼哼~一開始選這主題只能說我心臟有點大顆,過程中經常苦惱著該怎麼準備下一篇文章;沒想到一晃眼30天過去了,等等,RxJS還有很多還沒說完學完呢! XD

當然,完賽,就是一種肯定,一種榮耀
我覺得自己又進步了一點點,信心也跟著多了一點點
超爽!你也這麼覺得,是吧!

  • 後續我仍然會持續把RxJS的學習心得分享給各位,各位也請持續的關注喔!!/images/emoticon/emoticon12.gif


上一篇
菜雞們一起征服RxJS - day29: 所有客服人員都在忙線中,請稍後再播~謝謝 ~ exhaustAll, exhaustMap
下一篇
菜雞們一起征服RxJS - day31: 在observable執行"之前(startWith)"以及"最後(endWith)"幫我放入資料
系列文
菜雞也能優雅的征服RxJS32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
蛋蛋騎兵
iT邦新手 5 級 ‧ 2023-03-29 17:02:04

請教一下小偉哥,
1.為什麽當狀態碼為404的情況時,ajax.getJSON和ajax的輸出結果是一致的呢?
2.演示代碼中的return of(error);為什麽要加上of,直接return error不行。
感谢!

小偉哥 iT邦新手 4 級 ‧ 2023-03-30 16:47:46 檢舉

Hi 蛋蛋騎兵
(1) 我上面有說明這兩者的差異,如下:

  • ajax(URL): 取得backend回傳的資料,你可以進一步解析status是否為200,或者response的JSON資料...等。
  • ajax.getJSON(URL):直接解析response回傳的JSON資料

(2) 可以,不過對於RxJS來說,你如果想要串接另一個Observable,就得回傳一個Observable,你可以看一下我畫的流程圖。

你可以做個小實驗,直接回傳error,RxJS直接執行Observer的error後就結束了!

我要留言

立即登入留言