and*_*rew 29 javascript reactjs axios
尝试使timeout
axios 工作的方法时遇到问题。
为了测试:我故意设置了一个错误的 API 端点:它接受请求,抛出错误(例如:)throw new Error(\xe2\x80\x9ctesting for timeout\xe2\x80\x9d)
并且故意不执行任何其他操作。
一旦我调用测试 API 端点,我的客户端应用程序 (reactJS) 就会挂起 - 我预计它会在 2 秒内超时(我设置的超时)。我可以验证该应用程序正在与服务器建立联系。只有当我终止测试 API 服务器时,我的客户端应用程序才会立即继续。
\n示例代码:
\nconst axios = require(\'axios\')\n\nconst test1Press = async () => {\n try\n {\n await axios.post(\'https://mynodeserver.com/api/debug/throw\', {timeout: 2000})\n console.log("post call passed")\n }\n catch (err)\n {\n console.log("post call failed")\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n编辑(~2020):
\n经过进一步研究,看起来 axiostimeout
仅适用于响应超时,而不适用于连接超时。针对连接超时的建议解决方案是取消方法(例如signal
、cancelToken (deprecated)
):
对此进行了测试并工作:
\nconst source = CancelToken.source();\ntry {\n let response = null;\n setTimeout(() => {\n if (response === null) {\n source.cancel();\n }\n }, 2000);\n \n response = await axios.post(\'/url\',null,{cancelToken: source.token});\n // success\n} catch (error) {\n // fail\n}\n
Run Code Online (Sandbox Code Playgroud)\n
Đăn*_*inh 27
使用await axios.post('/debug/throw', {timeout: 2000})
,实际上您将有效负载发送 {timeout: 2000}
到服务器,而不是将超时设置为 2 秒。请参阅此处的示例。
我用 axios 的另一种语法进行了测试,它有效
const test1Press = async () => {
console.log("test1 pressed")
// obviously not the actual url in this stackoverflow post
axios.defaults.baseURL = 'http://localhost:9000'
console.log("pre call")
console.log(new Date().toUTCString());
try {
await axios({
method: 'post',
url: '/',
timeout: 2000 // only wait for 2s
})
console.log(new Date().toUTCString());
console.log("post call passed")
}
catch (err) {
console.log(new Date().toUTCString());
console.log("post call failed")
}
}
test1Press();
Run Code Online (Sandbox Code Playgroud)
在服务器端,我等待5秒,客户端出现超时错误
const http = require('http');
const server = http.createServer(function (req, res) {
setTimeout(function () {
res.write('Hello World!');
res.end();
}, 5 * 1 * 1000); // after 5s
})
.listen(9000);
Run Code Online (Sandbox Code Playgroud)
运行上面的代码 2 秒后出现超时错误
test1 pressed
pre call
Mon, 28 Jun 2021 09:01:54 GMT
Mon, 28 Jun 2021 09:01:56 GMT
post call failed
Run Code Online (Sandbox Code Playgroud)
编辑 我测试创建 axios 实例,这给了我相同的结果:
const test1Press = async () => {
console.log("test1 pressed")
// obviously not the actual url in this stackoverflow post
const instance = axios.create({
baseURL: 'http://localhost:9000',
timeout: 2000,
});
console.log("pre call")
console.log(new Date().toUTCString());
try {
await instance.post('/');
console.log(new Date().toUTCString());
console.log("post call passed")
}
catch (err) {
console.log(new Date().toUTCString());
console.log("post call failed")
}
}
test1Press();
Run Code Online (Sandbox Code Playgroud)
正如@arthankamal 答案中所示,timeout
属性仅负责响应超时,但不负责连接超时。要解决连接超时问题,请使用axios 的取消方法。基于较新的signal
属性添加以下示例(cancelToken
已弃用)。
signal
内置AbortSignal.timeout()的示例[需要 Nodejs 17.3+]:
axios({
method: 'get',
url: '/foo/bar',
timeout: 5000,
signal: AbortSignal.timeout(5000) //Aborts request after 5 seconds
})
.then(function(response) {
//...
});
Run Code Online (Sandbox Code Playgroud)
带有signal
超时辅助函数的示例:
function newAbortSignal(timeoutMs) {
const abortController = new AbortController();
setTimeout(() => abortController.abort(), timeoutMs || 0);
return abortController.signal;
}
axios({
method: 'get',
url: '/foo/bar',
timeout: 5000,
signal: newAbortSignal(5000) //Aborts request after 5 seconds
})
.then(function(response) {
//...
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
122331 次 |
最近记录: |