以前在js中請求網(wǎng)絡(luò)數(shù)據(jù)都是使用XMLHttpRequest
實現(xiàn)的
Fetch
的引入為JavaScript
提供了一個更好的替代方法,遺憾的是,fetch
沒有設(shè)置timeOut的設(shè)置,這里。。。。
fetch()
的詳細用法不在這里多說了,不清楚的自行Google
這里記錄如何設(shè)置請求超時時間
普通的post請求
這是一個普通的POST請求
fetch(url).then((response)=>{
response.json()
}).then((responseJson)=>{
console.log(responseJson)
}))
如何設(shè)置timeOut?往下看
Promise.race
-
Promise.race
接收一個promise對象數(shù)組為參數(shù)。 - 只要有一個
promise
對象進入Resolved
或者Rejected
狀態(tài)的話,就會繼續(xù)進行后面的處理。 - 通俗講就是多個
promise
“比賽”,誰先跑出結(jié)果(成功或失?。┚筒杉{誰
有了Prominse
的這個方法就可以有這樣的嘗試: 在一個新的Promise.race
中添加一個TimerPromise
,當(dāng)post
請求所在的Promise
在timer結(jié)束時仍沒有返回結(jié)果(成功或失?。?,那么就改變TimerPromise
的狀態(tài)(改為Resolved
或者 Rejected
),讓Prominse.race
收到超時的結(jié)果
TimerPromise長這樣
let timeoutAction = null;
const timerPromise = new Promise((resolve, reject) => {
timeoutAction = () => {
reject('請求超時');
}
})
使用Promise.race構(gòu)造新的fetch方法
const _fetch = (requestPromise, timeout=30000) => {
let timeoutAction = null;
const timerPromise = new Promise((resolve, reject) => {
timeoutAction = () => {
reject('請求超時');
}
})
setTimeout(()=>{
timeoutAction()
}, timeout)
return Promise.race([requestPromise,timerPromise]);
}
requestPromise
是post
請求的Promise
簡單的包裝
const post = (params) => {
const {url,successMsg,body} = params;
const jsonBody = JSON.stringify(params.body)
const myFetch = fetch(url,{
method: 'post',
headers:{
"Accept": "application/json",
"Content-Type" : "application/json"
},
body:jsonBody,
})
return new Promise((resolve, reject) => {
_fetch(myFetch, 30000)
.then(response => {
return response.json();
})
.then(responseData=>{
resolve(responseData)
})
.catch(error=>{
ToastMessage('網(wǎng)絡(luò)錯誤?');
reject(error);
});
});
}
export default post
這種曲線救國的方法有一個弊端:
在到達設(shè)定的超時時間仍沒有收到fetch的結(jié)果時,發(fā)出超時的消息,而真正的fetch也許仍在繼續(xù),好比設(shè)定30s的超時時間,雖然到了30s的時候沒有結(jié)果會收到超時的消息,但可能就在下一秒(第31s)收到fetch的結(jié)果。。。
是不是尷尬。。。
是。。。