以前在js中请求网络数据都是使用XMLHttpRequest实现的
Fetch的引入为JavaScript提供了一个更好的替代方法,遗憾的是,fetch没有设置timeOut的设置,这里。。。。
fetch()的详细用法不在这里多说了,不清楚的自行Google
这里记录如何设置请求超时时间
普通的post请求
这是一个普通的POST请求
fetch(url).then((response)=>{
response.json()
}).then((responseJson)=>{
console.log(responseJson)
}))
如何设置timeOut?往下看
Promise.race
-
Promise.race接收一个promise对象数组为参数。 - 只要有一个
promise对象进入Resolved或者Rejected状态的话,就会继续进行后面的处理。 - 通俗讲就是多个
promise“比赛”,谁先跑出结果(成功或失败)就采纳谁
有了Prominse的这个方法就可以有这样的尝试: 在一个新的Promise.race中添加一个TimerPromise,当post请求所在的Promise在timer结束时仍没有返回结果(成功或失败),那么就改变TimerPromise的状态(改为Resolved 或者 Rejected),让Prominse.race收到超时的结果
TimerPromise长这样
let timeoutAction = null;
const timerPromise = new Promise((resolve, reject) => {
timeoutAction = () => {
reject('请求超时');
}
})
使用Promise.race构造新的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('网络错误?');
reject(error);
});
});
}
export default post
这种曲线救国的方法有一个弊端:
在到达设定的超时时间仍没有收到fetch的结果时,发出超时的消息,而真正的fetch也许仍在继续,好比设定30s的超时时间,虽然到了30s的时候没有结果会收到超时的消息,但可能就在下一秒(第31s)收到fetch的结果。。。
是不是尴尬。。。
是。。。