让Fetch()也可以Timeout

    xiaoxiao2021-03-25  103

    以前在js中请求网络数据都是使用XMLHttpRequest实现的http://www.jianshu.com/p/8556d4394a5d 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的结果。。。 是不是尴尬。。。 是。。。

    转载请注明原文地址: https://ju.6miu.com/read-34510.html

    最新回复(0)