Javascript 逐个运行几个exec()命令

Javascript 逐个运行几个exec()命令,javascript,node.js,child-process,Javascript,Node.js,Child Process,我需要一个接一个地运行两个shell命令。这些命令被包装到函数中: function myFucn1() { exec('some command', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); throw error; }

我需要一个接一个地运行两个shell命令。这些命令被包装到函数中:

function myFucn1() {
     exec('some command',
        (error, stdout, stderr) => {
            if (error) {
                console.error(`exec error: ${error}`);
                throw error;
            }
            console.log(`stdout: ${stdout}`);
            console.error(`stderr: ${stderr}`);
        });
}

当我在触发器函数上调用它们时:

app.get('/my_end_point', (req, res) => {
    try {
        myFucn1();
        myFucn2();
        res.send('Hello World, from express');
    } catch (err) {
        res.send(err);
    }
});

它以随机顺序运行两个命令并输出stdout,stderr仅从第二个函数显示。

这是由于Javascript回调函数的性质。调用Exec函数,当结果可用时调用{}中的函数(所以命令可能会完成)。函数立即退出,第二个函数甚至在命令完成之前执行

一个可能的解决方案(尽管不是很好)是将myFucn2()的调用放在myFucn1()的回调中(例如:在console.error之后)

正确的解决方案是使用单独的线程(请参阅“工作线程”)跟踪myFucn1()的执行,并在它完成后执行第二个线程

您可以使用而不是exec来同步执行命令

const { execSync } = require("child_process");

function myFucn1() {
  return execSync("echo hello").toString();
}
function myFucn2() {
  return execSync("echo world").toString();
}

myFucn1();
myFucn2();

命令每次执行的顺序不同的原因是,它们一个接一个地被启动,但从那时起,JS无法控制它们执行的时间。对于像你这样的项目,基本上是这样的:

launch cmd1, then do callback1
launch cmd2, then do callback2
respond to the client
您无法控制何时执行
callback1
callback2
。根据您的描述,您正面临以下问题:

launch cmd1
launch cmd2
respond to the client
callback2
(something else happens in your program)
callback1
这就是为什么你只看到你所看到的


所以,让我们试着强制他们执行死刑!您可以使用,但我不建议在生产环境中使用,因为它会使您的服务器程序在子进程执行的整个过程中保持空闲

但是,通过使用async/await并将exec转换为异步函数,可以使用非常类似的语法:

app.get('/my_end_point', (req, res) => {
    try {
        myFucn1();
        myFucn2();
        res.send('Hello World, from express');
    } catch (err) {
        res.send(err);
    }
});
const{exec:execWithCallback}=require('child_process');
const{promisify}=require('util');
const exec=promisify(execWithCallback);
异步函数myFunc1(){
试一试{
const{stdout,stderr}=await exec('command 1');
}捕获(错误){
错误(`exec error:${error}`);
投掷误差;
}
}
//myFunc2也一样
对于您的服务器:

app.get('/my\u end\u point',异步(req,res)=>{
试一试{
等待myFunc1();
等待myFunc2();
res.send(‘世界你好,来自快递’);
}捕获(错误){
res.send(错误);
}
});

make myFucn1();返回一些内容,并使用if执行myFucn2。永远不要使节点行为同步。总是尝试自然的方式。否则性能可能会最差。出于上述目的,使用WebSocket就不必担心请求超时。您可以轻松地运行异步函数,并在正确的时间获得结果。这很简单,也可以工作,但在尝试执行时不鼓励这样做,因为它在执行子进程的整个过程中都会阻止事件循环,所以我同意并承认您的答案是更好的
myFunc1
myFunc2
彼此不依赖,所以这个解决方案并不令人满意。正确的解决方案是对这两个函数进行约定,然后使用
Promise.all
So
wait Promise.all(myFunc1(),myFunc2())@CristianTraìna这只是在命令不需要按顺序运行的特定情况下