node js一个接一个执行python脚本
Node js execute python script one after the other
我有一个 React 应用程序,我想在单击按钮时一个接一个地使用 Node 执行多个脚本(可以是 N 个脚本)。我也有每个脚本的一些状态,所以当脚本完成时我想将他的状态设置为“完成”。
经过一些 google-ing 我最终得到了:
function runScript(command, args, options, id, callback) {
const child = childProcess.spawn(command, args, options);
child.stdout.on('data', (data) => {
console.log(`${data}`);
});
child.stderr.on('data', (data) => {
console.log(`${data}`);
});
// callback function to change the state to "completed"
child.on('close', () => callback(id, 'completed'));
}
const deployScripts = () => {
loadedSteps.forEach((script) => {
if (script.path.length) {
const [command, args, options] = getParamBasedOnFile(script.path);
if (command) {
//set the script to "active" which means is running
updateStepStatus(script.id, 'active');
runScript(command, args, options, script.id, updateStepStatus);
}
}
});
};
它有效,但当然因为它的异步是 运行 所有脚本同时运行,这不是我想要的。
然后我去尝试同步
function runScript(command, args, options) {
const child = childProcess.spawnSync(command, args, options);
console.log(child.stdout.toString());
// callback(id, 'completed'); -> doesnt work
console.log('exit run script function');
}
const deployScripts = () => {
loadedSteps.forEach((script) => {
if (script.path.length) {
const [command, args, options] = getParamBasedOnFile(script.path);
if (command) {
updateStepStatus(script.id, 'active');
runScript(command, args, options, script.id, updateStepStatus);
updateStepStatus(script.id, 'completed');
}
}
});
};
但问题在于,即使它一个接一个地运行脚本(我可以在控制台中看到输出),两个脚本状态同时设置为“完成”(当我测试时它 1 python 脚本有 5 秒的睡眠,另一个有 10 秒的睡眠,所以第一个应该设置为完成,然后在 5 秒后第二个)。
不确定这样做的最佳方法是什么。
您可以承诺 runScript
并将一系列步骤实现为 async
函数,这样您就可以使用 await
等待每个步骤完成,然后再 运行 next步骤.
const childProcess = require("child_process")
/* mocks */
const loadedSteps = [{path:'foo', id:1}, {path:'bar', id:2}, {path:'baz', id:3}]
function getParamBasedOnFile(path) {
return ['python', ['-c', "import time;time.sleep(1)"], {}]
}
function updateStepStatus(id, status) {
console.log(id, status)
}
/* code */
function runScript(command, args, options) {
return new Promise((resolve, reject) => {
const child = childProcess.spawn(command, args, options);
child.on('close', () => resolve(child.stdout.toString()))
})
}
async function deployScripts() {
for(const script of loadedSteps) {
if (script.path.length) {
const [command, args, options] = getParamBasedOnFile(script.path);
if (command) {
updateStepStatus(script.id, 'active');
await runScript(command, args, options, script.id);
updateStepStatus(script.id, 'completed');
}
}
}
};
/* main */
deployScripts().then(() => console.log('done'))
我有一个 React 应用程序,我想在单击按钮时一个接一个地使用 Node 执行多个脚本(可以是 N 个脚本)。我也有每个脚本的一些状态,所以当脚本完成时我想将他的状态设置为“完成”。
经过一些 google-ing 我最终得到了:
function runScript(command, args, options, id, callback) {
const child = childProcess.spawn(command, args, options);
child.stdout.on('data', (data) => {
console.log(`${data}`);
});
child.stderr.on('data', (data) => {
console.log(`${data}`);
});
// callback function to change the state to "completed"
child.on('close', () => callback(id, 'completed'));
}
const deployScripts = () => {
loadedSteps.forEach((script) => {
if (script.path.length) {
const [command, args, options] = getParamBasedOnFile(script.path);
if (command) {
//set the script to "active" which means is running
updateStepStatus(script.id, 'active');
runScript(command, args, options, script.id, updateStepStatus);
}
}
});
};
它有效,但当然因为它的异步是 运行 所有脚本同时运行,这不是我想要的。
然后我去尝试同步
function runScript(command, args, options) {
const child = childProcess.spawnSync(command, args, options);
console.log(child.stdout.toString());
// callback(id, 'completed'); -> doesnt work
console.log('exit run script function');
}
const deployScripts = () => {
loadedSteps.forEach((script) => {
if (script.path.length) {
const [command, args, options] = getParamBasedOnFile(script.path);
if (command) {
updateStepStatus(script.id, 'active');
runScript(command, args, options, script.id, updateStepStatus);
updateStepStatus(script.id, 'completed');
}
}
});
};
但问题在于,即使它一个接一个地运行脚本(我可以在控制台中看到输出),两个脚本状态同时设置为“完成”(当我测试时它 1 python 脚本有 5 秒的睡眠,另一个有 10 秒的睡眠,所以第一个应该设置为完成,然后在 5 秒后第二个)。
不确定这样做的最佳方法是什么。
您可以承诺 runScript
并将一系列步骤实现为 async
函数,这样您就可以使用 await
等待每个步骤完成,然后再 运行 next步骤.
const childProcess = require("child_process")
/* mocks */
const loadedSteps = [{path:'foo', id:1}, {path:'bar', id:2}, {path:'baz', id:3}]
function getParamBasedOnFile(path) {
return ['python', ['-c', "import time;time.sleep(1)"], {}]
}
function updateStepStatus(id, status) {
console.log(id, status)
}
/* code */
function runScript(command, args, options) {
return new Promise((resolve, reject) => {
const child = childProcess.spawn(command, args, options);
child.on('close', () => resolve(child.stdout.toString()))
})
}
async function deployScripts() {
for(const script of loadedSteps) {
if (script.path.length) {
const [command, args, options] = getParamBasedOnFile(script.path);
if (command) {
updateStepStatus(script.id, 'active');
await runScript(command, args, options, script.id);
updateStepStatus(script.id, 'completed');
}
}
}
};
/* main */
deployScripts().then(() => console.log('done'))