我正在使用异步函数来启动服务器,检查url是否返回200,然后运行测试,但是在运行下一行代码之前,我的checkUrl函数未完成。

我正在使用axios包ping状态代码的url,并且我一直在尝试async / await和Promise.resolve()的几种变体。

function checkUrl(url) {
  console.log(`Checking for ${url}`);

  return axios
    .get(url)
    .then(function(res) {
      const message = `${url} is status code: ${res.status}`;

      return res;
    })
    .catch(function(err) {
      console.log("Will check again in 5 seconds");
      setTimeout(() => {
        return checkUrl(url);
      }, 5000);
    });
}

async function init() {
  let val;

  console.log("Running tests:::");
  // start server in react-integration directory
  shell.exec("BROWSER=none yarn start", {
    cwd: "sampleIntegration/react-integration",
    async: true
  });
  // check server has started
  val = await checkUrl("http://localhost:3000");

  console.log(`value from checkUrl promise: ${val}`);
}


我期望val变量是Promise.resolve()函数中checkUrl返回的消息。

val返回未定义。

最佳答案

问题是catch块中的setTimeout。这是异步的,但是catch块立即返回。由于它没有任何要返回的内容,因此返回undefined。要解决此问题(并保持所需的等待行为),您可以执行以下操作:

function checkUrl(url) {
  console.log(`Checking for ${url}`);

  return axios.get(url)
    .then(res => {
      const message = `${url} is status code: ${res.status}`;
      return res;
    })
    .catch(err => {
      console.log('Will check again in 5 seconds');
      return new Promise((resolve) => {
         setTimeout(resolve, 5000);
      }).then(() => checkUrl(url));
    });
}


这将产生一个Promise,它会在5秒钟后解析,并在解析后调用checkUrl。

09-07 16:27