前言
大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心
Promise封裝請求
大家平時如果使用 Promise
封裝請求,那麼當你使用這個請求函式的時候是這樣的:
// 封裝請求函式
const request = (url, params) => {
return new Promise((resolve, reject) => {
// ...do something
})
}
// 使用時
const handleLogin = () => {
request(
'/basic/login',
{
usename: 'sunshine',
password: '123456'
}
).then(res => {
// success do something
}).catch(err => {
// fail do something
})
}
可以看到,當你的請求成功時,會呼叫 then
方法,當你的請求失敗時會呼叫 catch
方法。
async/await
Promise
的出現解決了很多問題,但是如果請求多了且有順序要求的話,難免又會出現 巢狀
的問題,可讀性較差,比如:
const handleLogin = () => {
request(
'/basic/login',
{
usename: 'sunshine',
password: '123456'
}
).then(res => {
// 登入成功後獲取使用者資訊
request(
'/basic/getuserinfo',
res.id
).then(info => {
this.userInfo = info
}).catch()
}).catch(err => {
// fail do something
})
所以這個時候 async/await
出現了,他的作用是:用同步的方式執行非同步操作,上面的程式碼使用 async/await
的話可以改寫成:
const handleLogin = async () => {
const res = await request('/basic/login', {
usename: 'sunshine',
password: '123456'
})
const info = await request('/basic/getuserinfo', {
id: res.id
})
this.userInfo = info
}
這樣的話程式碼的可讀性比較高,而不會出現剛剛的巢狀問題,但是現在又有一個問題了,Promise有 catch
這個錯誤回撥來保證請求錯誤後該做什麼操作,但是 async/await
該如何捕獲錯誤呢?
async-to-js
其實已經有一個庫 async-to-js
已經幫我們做了這件事,我們可以看看它是怎麼做的,它的原始碼只有 短短十幾行
,我們應該讀讀它的原始碼,學學它的思想
原始碼很簡單
/**
* @param { Promise } 傳進去的請求函式
* @param { Object= } errorExt - 擴充錯誤物件
* @return { Promise } 返回一個Promise
*/
export function to(
promise,
errorExt
) {
return promise
.then(data => [null, data])
.catch(err => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt)
return [parsedError, undefined]
}
return [err, undefined]
})
}
export default to
原始碼總結:to
函式返回一個Promise且值是一個陣列,陣列之中有兩個元素,如果索引為0
的元素不為空值,說明該請求報錯,如果索引0
的元素為空值說明該請求沒有報錯,也就是成功。
使用很簡單
我們該怎麼去使用這個 to
函式呢?其實很簡單,還是剛剛的例子
const handleLogin = async () => {
const [resErr, res] = await to(request('/basic/login', {
usename: 'sunshine',
password: '123456'
}))
if (resErr) {
// fail do somthing
return
}
const [userErr, info] = await to(request('/basic/getuserinfo', {
id: res.id
}))
if (userErr) {
// fail do somthing
return
}
this.userInfo = info
}
所以說,偶爾看看一些庫的原始碼,還是能學到東西的!!!
結語
我是林三心,一個熱心的前端菜鳥程式設計師。如果你上進,喜歡前端,想學習前端,那我們們可以交朋友,一起摸魚哈哈,摸魚群,加我請備註【思否】