Платформа:
У меня есть API в sails.js и интерфейс в реагирует .Вызовы между передней и задней панелями выполняются с помощью fetch api .
Дополнительная информация:
В ходе некоторых конечных точек API, которые я имеючтобы выполнить внешний файл, на этом этапе я использую функцию execfile () из node.js , и мне приходится ждать, пока он будет выполнен, чтобы ответить на внешний интерфейс.
В чем проблема?
Если файл выполняется за короткое время, например, менее 1 минуты, все работает хорошо, и поведение происходит так, как ожидается на обоихсторон, но если (в этом случае) выполнение файла занимает более 1 минуты, есть что-то, чтобы вызвать второй вызов api (я не знаю, где это вызывается, но я тестировал ту же конечную точку с почтальон и у меня не было этой проблемы, поэтому я подозреваю, что реагирует / fetch-api) , и вызов API с теми же данными из первого вызова повторяется.Это приводит к тому, что файл запускается дважды.
Еще более странным является то, что если у вас включен сетевой инспектор DevTools, этот второй вызов не появляется, но ничто в документации по 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);
}
});
}
};
Пример реакции компонента на вызов fetch:
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 часов, файл может быть вызван только один раз и когда он завершится, тогда да, он может вернуться к веб-интерфейсу.
Обратите внимание, что примеры не имеют исходного кода и не были протестированы.Это упрощенная версия кода для объяснения поведения