如何在nodejs中同步执行?

时间:2018-03-29 07:44:34

标签: javascript node.js express async-await

我有以下代码。

router.post('/',function(req, res, next) {
        var id=req.body.id;
        console.log(id);

    const testscript = exec('sh script.sh');

    testscript.stdout.on('data', function(data){
        console.log(data);
        // sendBackInfo();
    });

    testscript.stderr.on('data', function(data){
        console.log(data);
        // triggerErrorStuff();
    });

        res.redirect('/Visualise');
});

我需要完全执行我的shell脚本,然后重定向到'/ Visualize'。下一页中的部分代码使用shell脚本生成的输出文件。它在完全执行shell脚本之前重定向,我得到一个文件未找到错误。 我怎样才能同步执行。请在上面的代码中进行必要的更改。谢谢。

2 个答案:

答案 0 :(得分:1)

您可以使用child_process.execSync,它返回stdout:

child_process.execSync(command[, options])

e.g。

const child_process = require('child_process');
var response = child_process.execSync('sh script.sh');

响应将是一个Buffer对象。

文件在这里:

https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options

请注意,如果脚本超时或退出代码非零,则此方法将引发错误,因此您可能希望使用try / catch包装。

要将此添加到您的代码,请执行以下操作:

const child_process = require('child_process');

router.post('/',function(req, res, next) {
        var id=req.body.id;
        console.log(id);    

        try
        {
            var response = child_process.execSync('sh script.sh');
            console.log('Script response: ', response.toString());
        }
        catch (error) {
            console.error('An error occurred: ', error);
        }

        res.redirect('/Visualise');
});

更好的模式是异步执行此操作:

const child_process = require('child_process');

router.post('/',function(req, res, next) {
        var id=req.body.id;
        console.log(id);    

        child_process.exec('sh script.sh', (error, stdout) => {
            if (error) {
                console.error(`exec error: ${error}`);
                return;
            }
            console.log(`stdout: ${stdout}`);

            res.redirect('/Visualise');
        });
});

注意:从未将未经过处理的用户输入传递给此功能,这是一个很大的安全风险。

答案 1 :(得分:1)

您真正想要的不是同步执行脚本,因为这会阻止事件循环并阻止其他请求运行。相反,您需要(异步)等待脚本完成。

为此,请在子进程的exit事件内写入重定向,而不是在处理程序的主体上:

router.post('/', function(req, res, next) {
    // ...whatever

    const testscript = exec('sh script.sh');

    // ...stdouts

    testscript.on('exit', function (code, signal) {
        res.redirect('/Visualise');
    });
});