Fetch 簡單封裝

fetch 返回的是一個 Promise 對象, 每個 promise 對象最后會有 resolve 或 reject 兩種狀態, then 方法是 promise 對象的方法, then 方法返回的也是一個 promise 對象,所以 then 可以連著寫。

get = (url) =>
  fetch(url, {
    method: 'GET',
  }).then(resp => Promise.all([resp.ok, resp.status,resp.json()])
  ).then(([ok, status, json]) => {
    if (ok) {
      return json;
    } else {
      this.handleError(status, json.error);
      throw new Error(json.error);
    }
  }).catch(error => {
    throw error;
  });

post = (url, body) => this._request(url, body, 'POST');

put = (url, body) => this._request(url, body, 'PUT');

_delete = (url, body) => this._request(url, body, 'DELETE');

_request = (url, body, method) =>
  fetch(url, {
    method: method,
    body: JSON.stringify(body)
  }).then(resp => {
    return Promise.all([resp.ok, resp.status, resp.json()]);
  }).then(([ok, status, json]) => {
    if (ok) {
      return json;
    } else {
      this.handleError(status, json.error);
      throw new Error(json.error);
    }
  }).catch(error => {
    throw error;
  });

fetch 對所有的 response code 包括 200X 300X 400X 500X 等返回的都是 resolve 狀態, 只有拋異常時才會走到 catch 里面, 所以我們希望把 非200X 請求作為 reject 狀態區分出來, 在 REST API 中 300X 400X 500X 的狀態碼通常意外著錯誤,服務端通常還會返回一個 errorCode 和 errorMessage 來表示錯誤原因。

所以很簡單直接通過 response code 區分出來就行了 : if (response.status >= 200 && response.code < 300)。 fetch 的 Response 對象的 ok 屬性就是干這個事情的

if (response.ok) {
  return json;
} else {
  throw new Error(json.error);
}

ok 時直接返回 json, 其它情況拋出異常, 所有的異常放到 catch 里面去處理, 拋異常時當前 promise 也是 reject 狀態,我們應該把這個異常繼續拋出這樣外界調用時就可以用 catch 進行異常處理了。

這里我們用了 Promise.all([resp.ok, resp.status,resp.json()]) 把 ok status response.json() 都放到一個 then 里面去處理, 因為非 ok 時我們也要從 response.json() 中拿錯誤信息。

注意 response.json() 返回的也是一個 Promise 對象

Promise.all 可以組合多個 Promise ,只有所有的 promise 都 resolve 時其結果才會是 resolve, 只要有一個 reject 結果就是 reject 狀態。 如果數組中元素不是 promise 對象會先轉為 promise 對象。

注意在 catch 里面拋出異常, 這個 promise 就是 reject 狀態, 在外面可以這樣使用

getUsers() {
    return get('/api/users').then(json => {
      return json;
    }).catch(error=>{
      // 這里處理錯誤
    });
}

注意我們每次都返回了一個 Promise 對象 (fetch 本身返回的就是 Promise) 所以使用的時候可以級聯寫
我們調用 getUsers 的時候就可以這樣寫

getUsers.then(json => {
  // 處理數據
  return json;
}).catch(error=>{
    
});

每一個方法都返回 Promise 對象, 我們可以一層一層的根據自己的實際情況處理數據。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Promiese 簡單說就是一個容器,里面保存著某個未來才會結束的事件(通常是一個異步操作)的結果,語法上說,Pr...
    雨飛飛雨閱讀 3,373評論 0 19
  • 00、前言Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區...
    夜幕小草閱讀 2,139評論 0 12
  • Promise的含義: ??Promise是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和...
    呼呼哥閱讀 2,189評論 0 16
  • //本文內容起初摘抄于 阮一峰 作者的譯文,用于記錄和學習,建議觀者移步于原文 概念: 所謂的Promise,...
    曾經過往閱讀 1,251評論 0 7
  • 既見君子,云胡不喜 20170123 (原諒我用這句古老的詩句作為題目,因為我要寫的這個人的這種行為,真的就是君子...
    河南麥子的書寫閱讀 1,262評論 5 2