javascript 如何处理挂起API服务器的Axios超时?

xj3cbfub  于 2022-12-10  发布在  Java
关注(0)|答案(3)|浏览(197)

尝试使axios的timeout方法工作时出现问题。
测试:我故意设置了一个错误API端点:它接受请求,抛出错误(例如:throw new Error(“testing for timeout”))并且故意不做其他事情。
我的客户端应用程序(reactJS)挂起,一旦我作出调用测试API端点-我希望它在2秒内超时(我的设置超时)。我可以验证应用程序正在与服务器联系。它只有当我杀死我的测试API服务器,我的客户端应用程序立即继续。
样本代码:

const axios = require('axios')

const test1Press = async () => {
  try
  {
    await axios.post('https://mynodeserver.com/api/debug/throw', {timeout: 2000})
    console.log("post call passed")
  }
  catch (err)
  {
    console.log("post call failed")
  }
}

编辑日期(~2020年):

进一步研究发现,axios timeout只适用于响应超时,而不适用于连接超时。建议的连接超时解决方案是cancellation methods(例如signalcancelToken (deprecated)):
已测试并正常工作:

const source = CancelToken.source();
try {
  let response = null;
  setTimeout(() => {
    if (response === null) {
      source.cancel();
    }
  }, 2000);
        
  response = await axios.post('/url',null,{cancelToken: source.token});
  // success
} catch (error) {
  // fail
}
nc1teljy

nc1teljy1#

假设您通过axios请求URL,而服务器需要很长时间才能响应,在这种情况下,axios超时将起作用。
但你没有互联网连接或IP地址或域名,你要求不存在,在这种情况下,axios超时将不工作.
See original answer for solution

rjjhvcjd

rjjhvcjd2#

如@arthankamal答案所示,timeout属性仅负责响应超时,而不负责连接超时。若要解决连接超时问题,请使用axios's cancellation methods。添加以下基于较新signal属性的示例(不推荐使用cancelToken)。

示例内置signalAbortSignal.timeout() [需要节点js 17.3以上版本]:

axios({
  method: 'get',
  url: '/foo/bar',
  timeout: 5000,
  signal: AbortSignal.timeout(5000) //Aborts request after 5 seconds
})
.then(function(response) {
  //...
});

示例,使用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) {
  //...
});
lsmepo6l

lsmepo6l3#

使用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();

在服务器端,我等待了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);

运行上面的代码,2秒后出现超时错误

test1 pressed
pre call
Mon, 28 Jun 2021 09:01:54 GMT
Mon, 28 Jun 2021 09:01:56 GMT
post call failed

EDIT我测试了创建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();

相关问题