以前在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的结果。。。
是不是尴尬。。。
是。。。