我正在尝试通过获取请求从服务器获取一些数据。有时网络会失败或发生类似的其他事情,我希望有一个超时以防止进一步的错误,并获得更好的体验。
实际上我想等待 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 秒后停止的实际请求。
请帮助我提供您的建议。感谢。
没有标准的参数可以添加到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。
"信号"传递到获取选项中来中止获取请求。
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();
Fetch 没有实现连接超时。您也无法中止抓取请求。
看看这个要点,它围绕抓取请求包裹了一个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,这是一种获取的替代方案,支持超时:https://github.com/axios/axios