【问题标题】:How not to wait for finishing child process in Node.js?如何不在 Node.js 中等待完成子进程?
【发布时间】:2021-06-02 13:54:29
【问题描述】:

实际上,我在异步函数中运行我的 exec 任务。执行后,软件启动并循环运行。

执行此操作后,我的 node.js 应用程序停止运行代码。

如何从 node.js 开始运行另一个应用程序并忽略结果并继续执行代码?

import util = require('util');

const exec = util.promisify(require('child_process').exec);
export class ExecClass{
    public static async run(...parameters: (number | string)[]) {
        const app=parameters[0];
        parameters=parameters.slice(1);
        const cmd = app+ " " + parameters.join(" ");
        const { stdout, stderr } = await exec(cmd);
    }
}

编辑

在我的调用代码之后,我只是在我的数据库中进行了一些编辑。

我的调用代码:

import {ExecClass} from "./exec-class";
async function run() {
    await ExecClass.run(cmd, data.id, data.startDate, data.endDate, data.idx);
}

【问题讨论】:

  • child_process.exec() 不会阻止。因此,您的 nodejs 程序应该能够在运行时执行其他操作。您能否显示调用代码以及调用此代码后您还期望做什么?
  • 我刚刚添加了我的调用代码
  • 这并没有显示任何有用的东西。你还想做什么。您的问题是“我的 node.js 应用程序停止使用代码”。那么,您还希望它执行什么,该代码在哪里?您是否看到任何错误?还是只是等到执行完成后再继续?
  • 它只是等到 exec 完成,然后它才继续我的代码。以下代码只是一些计算
  • 然后,如果您不想让您的代码等待它,只需删除ExecClass.run() 前面的await。不过,您应该在上面加上.catch(),这样您就不会遇到未处理的拒绝。

标签: node.js exec child-process


【解决方案1】:

我没有时间对此进行测试,但看起来您需要做的就是从 exec() 调用中删除 await 关键字。您也不再需要运行函数上的 async 修饰符。

import util = require('util');

const exec = util.promisify(require('child_process').exec);
export class ExecClass{
    public static run(...parameters: (number | string)[]) {
        const app=parameters[0];
        parameters=parameters.slice(1);
        const cmd = app+ " " + parameters.join(" ");
        const { stdout, stderr } = exec(cmd);
    }
}

现在您将不再能够将 exec 视为传统的同步函数,因此您必须将其改回回调格式:

import util = require('util');

const exec = util.promisify(require('child_process').exec);
export class ExecClass{
    public static run(...parameters: (number | string)[]) {
        const app=parameters[0];
        parameters=parameters.slice(1);
        const cmd = app+ " " + parameters.join(" ");
        exec(cmd, ({ stdout, stderr }) => {
           // do something with stdout or stderr here
        });
    }
}

但您最希望保持面向承诺的流程,以便我们可以将您的整个操作包装在一个承诺中:

import util = require('util');

const exec = util.promisify(require('child_process').exec);
export class ExecClass{
    public static run(...parameters: (number | string)[]) {
        return new Promise( (resolve, reject) => {
            const app=parameters[0];
            parameters=parameters.slice(1);
            const cmd = app+ " " + parameters.join(" ");
            exec(cmd, ({ stdout, stderr }) => {
               resolve({stdout, stderr});
            });
        })
    }
}

现在,您可以在调用进程继续执行操作的同时等待父调用代码中的 Promise 解决。此外,您可以在调用代码上处理承诺。

【讨论】:

  • 感谢您的回答,但我的父调用代码仍在等待 ExecClass 运行完成
  • 是否有另一种解决方案,用 args 启动软件?我不需要记录标准输出、标准输入和错误
  • 你的三个代码版本都是错误的。第一次尝试做const { stdout, stderr } = exec(cmd);,但exec() 在这里返回一个承诺,所以这将失败。在您的第二个和第三个代码块中exec() 在此代码中是child_process.exec 的承诺版本,它不接受回调,因此回调不会做任何事情。我知道您只是想删除await,但这不是必需的。如果调用代码只是没有await 从这个函数返回的承诺,它可以做任何它想做的事情。
  • 刚回来纠正那个错误,对不起,我不应该通过答案来驱动。
猜你喜欢
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 2011-06-26
  • 1970-01-01
相关资源
最近更新 更多