平台:
我在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个小时无关紧要,该文件只能被调用一次,并在完成时被调用,然后可以返回到前端。
请注意,这些示例没有原始代码,也没有经过测试。是解释行为的代码的简化版本
答案 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);
};