node js:child_process.exec实际上没有等待

时间:2018-05-09 10:13:59

标签: node.js async-await

请考虑这段代码:

var cmd = `cd "${dir}" && curl -L "${url}" | tar -xJvf - | zip -qr archive.zip -@`;
await exec(cmd);
res.sendFile(path.join(dir, "archive.zip"));

下载.tar.xz,解压缩并重新压缩并最终发送给用户。

如果我运行它,它会在res.sendFile(...)失败,说该文件不存在。但是,如果我查看我的文件系统,zip实际上就在那里。

所以我尝试在res.sendFile(...)之前添加一个小延迟,如下所示:

var cmd = `cd "${dir}" && curl -L "${url}" | tar -xJvf - | zip -qr archive.zip -@`;
await exec(cmd);

setTimeout(()=>{
    res.contentType(path.join(dir, "archive.zip"));
    res.sendFile(path.join(dir, "archive.zip"));
}, 1000);

......它神奇地工作了。

似乎exec(cmd)实际上并没有等待命令完成。是因为它是用管道输送的?

1 个答案:

答案 0 :(得分:2)

好的,exec并不像那样工作。

await关键字期望Promise等待。因为exec只会返回一个子进程对象,并且需要调用一个回调然后就绪,这不会起作用。

但节点中有一个util用于将这些常规节点函数转换为promise函数util.promisify。 nodejs.org/api/util.html#util_util_promisify_original

这也显示在exec的文档中(参见本段末尾的https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback



let util = require('util')
let exec = require('child_process').exec
let exec_prom = util.promisify(exec)

exec_prom('ip address').then(()=>{console.log('done')})


async function do(){
  await exec_prom('ip address');
  // do something after
}