node.js超时重新启动api调用

时间:2019-02-04 16:13:57

标签: javascript node.js reactjs sails.js fetch

平台:

我在sails.js中有一个api,在react中有一个前端。前端和后端之间的呼叫是通过fetch api进行的。

更多信息:

在某些api端点过程中,我必须执行一个外部文件,此时,我正在使用execfile()node.js函数,并且我必须等待它执行以响应到前端。

出了什么问题?

如果文件在短时间内执行,例如少于1分钟,则一切运行良好,并且行为均按预期发生,但是,如果(在这种情况下)文件执行超过1分钟,是触发对api 的第二次调用的东西(我不知道在哪里调用,但是我用postman测试了相同的端点,但是我没有这个问题,所以我怀疑react / fetch- api),并且重做第一次调用中具有相同数据的api调用。这将导致文件运行两次。

甚至更奇怪的是,如果您打开了DevTools Network检查器,则不会出现第二个调用,但是sailjs文档中没有任何内容指向此行为。

sails.js中的端点示例:

/**
 * FooController
 */
const execFile = require("child_process").execFile;
module.exports = {
  foo: async (req, res) => {
    let result = await module.exports._executeScript(req.body).catch(() => {
      res.status(500).json({ error: "something has occurred" });
    });
    res.json(result);
  },
  _executeScript: body => {
    return new Promise((resolve, reject) => {
      let args = [process.cwd() + "/scripts/" + "myExternalFile.js", body];
      let elem = await module.exports
        ._execScript(args)
        .catch(err => reject(err));
      resolve(elem);
    });
  },
  _execScript: args => {
    return new Promise((resolve, reject) => {
      try {
        execFile("node", args, { timeout: 150000 }, (error, stdout, stderr) => {
          if (error || (stderr != null && stderr !== "")) {
            console.error(error);
          } else {
            console.log(stdout);
          }
          let output = { stdout: stdout, stderr: stderr };
          resolve(output);
        });
      } catch (err) {
        reject(err);
      }
    });
  }
};

组件响应提取调用的示例:

import React from "react";
import { notification } from "antd";
import "./../App.css";
import Oauth from "./../helper/Oauth";
import Config from "./../config.json";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      syncInAction: false,
      data: null
    };
  }
  componentDidMount() {
    this.handleSync();
  }
  async handleSync() {
    let response = await fetch(Config.apiLink + "/foo/foo", {
      method: "POST",
      mode: "cors",
      headers: {
        Authorization: Oauth.isLoggedIn(),
        Accept: "application/json",
        "Content-Type": "application/json"
      },
      body: JSON.stringify(this.state.myData)
    }).catch(err => {
      notification.error({
        key: "catch-ApiFail",
        message: "Erro"
      });
    });

    let json = await response.json();
    this.setState({
      syncInAction: false,
      data: json
    });
  }
  render() {
    return <div>{this.state.data}</div>;
  }
}

export default App;

我的预期目标/行为是什么

通话时间为1分钟或10个小时无关紧要,该文件只能被调用一次,并在完成时被调用,然后可以返回到前端。

请注意,这些示例没有原始代码,也没有经过测试。是解释行为的代码的简化版本

1 个答案:

答案 0 :(得分:0)

我最终解决了这个问题,显然是在服务器上的nodejs has a default timing of 2 minutes,并且可以重写以错过此timout或增加它。 这只是在foo()端点的开头添加了一行代码,问题得以解决。

重做呼叫的行为是没有记录,并且使用邮递员时没有这种行为很奇怪,但这是任何需要它的人的解决方案。

最终结果:

foo: async (req, res) => {
  req.setTimeout(0);
  let result = await module.exports._executeScript(req.body).catch(() => {
    res.status(500).json({ error: "something has occurred" });
  });
  res.json(result);
};