我正在尝试通过获取请求从服务器获取一些数据。 有时网络会失败或发生类似的其他事情,我想超时以防止进一步的错误并获得更好的体验。
实际上,我想等待20秒,如果没有收到任何答复,我想显示错误并中断获取请求。
我有一个加载模式,可以通过超时关闭它,但是我也想破坏获取请求。
这是我的提取请求代码:
_testPress = async () => {
//setTimeout(() => {this.setState({loading: false})}, 20000)
this.setState({loading : true})
fetch(getInitUrl('loginUser'), {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
password : this.state.password,
email : this.state.emailAddress,
}),
}).then(response => Promise.all([response.ok, response.status ,response.json()]))
.then(([responseOk,responseStatus, body]) => {
if (responseOk) {
//console.log(responseOk, body);
this._signInAsync(body.token);
// handle success case
} else {
console.log(responseStatus);
this.setState({
showAlert : true,
alertType : true,
alertMessage : body.message
});
}
})
.catch(error => {
console.error(error);
// catches error case and if fetch itself rejects
});
}
我使用setTimeout关闭加载模块,但它不会停止实际的请求,我希望它在20秒后停止。
请帮助我。 谢谢。
答案 0 :(得分:1)
访存未实现连接超时。您也不能中止获取请求。
看看这个要点,它围绕着获取请求包裹了Promise.race
。只要其中一个承诺(获取或超时)解决或拒绝,该承诺就会解决:
https://gist.github.com/davej/728b20518632d97eef1e5a13bf0d05c7
类似的事情应该起作用:
Promise.race([
fetch(getInitUrl('loginUser'), *...fetchparams* ),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), 7000)
)
]).then(*stuff*).catch(*stuff*)
或者,您也可以尝试axios,这是fetch的替代方法,并支持超时: https://github.com/axios/axios
答案 1 :(得分:1)
没有可以添加到fetch
的标准参数,但是您可以执行以下操作:
// creating a wrapper for promises
function timeout(milliseconds, promise) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("timeout exceeded"))
}, milliseconds)
promise.then(resolve, reject)
})
}
// using that wrapper with fetch
timeout(1000, fetch('/api'))
.then(function(response) {
// response success
}).catch(function(error) {
// timeout error or server error
})
示例:
超时已超过:
// creating a wrapper for promises
function timeout(milliseconds, promise) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("timeout exceeded"))
}, milliseconds);
promise.then(resolve, reject);
});
}
const requestErr = new Promise((resolve, reject) => {
setTimeout(() => {
// request finished.
resolve();
}, 2500);
})
timeout(1000, requestErr)
.then(function(response) {
console.log("OK!");
}).catch(function(error) {
console.log("ERROR TIMEOUT!");
});
未超过超时时间:
// creating a wrapper for promises
function timeout(milliseconds, promise) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("timeout exceeded"))
}, milliseconds);
promise.then(resolve, reject);
});
}
const requestOk = new Promise((resolve, reject) => {
setTimeout(() => {
// request finished.
resolve();
}, 500);
})
timeout(1000, requestOk)
.then(function(response) {
console.log("OK!");
}).catch(function(error) {
console.log("ERROR TIMEOUT!");
});
您还可以使用具有自己的超时设置的AXIOS。
答案 2 :(得分:0)
您可以通过在获取选项中传递“信号”来中止获取请求。
AbortSignal对象实例;允许您与获取请求进行通信,并根据需要通过AbortController中止该请求。
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
完整的代码示例在这里。
https://javascript.info/fetch-abort
let controller = new AbortController();
fetch(url, {
signal: controller.signal
});
controller.abort();