繁体   English   中英

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

[英]node.js timeout restarts api call

平台:

我有一个API sails.js ,并在前端反应 前端和后端之间的调用是使用fetch api进行的

更多信息:

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

问题是什么?

如果文件在短时间内执行,例如少于1分钟,则一切运行良好,并且行为均按预期发生,但是,如果(在这种情况下)文件执行时间超过1分钟,则可能需要执行一些操作触发对api的第二次调用(我不知道在哪里调用,但是我用邮递员测试了相同的端点,但是我没有这个问题,所以我怀疑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个小时都没有关系,该文件只能被调用一次,并在完成时被调用,然后可以返回到前端。

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

我最终解决了这个问题,显然nodejs在服务器上的默认计时为2分钟 ,可以重写以错过或增加此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);
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM