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 對象, 我們可以一層一層的根據自己的實際情況處理數據。