Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 节点-以类形式写入子进程生成执行_Node.js_Child Process_Spawn - Fatal编程技术网

Node.js 节点-以类形式写入子进程生成执行

Node.js 节点-以类形式写入子进程生成执行,node.js,child-process,spawn,Node.js,Child Process,Spawn,我正在编写一个现有模块,它生成一个子进程并执行一个命令 我将它作为一个类重新编写,但是当我运行代码时,我得到了一个错误,承诺被拒绝,解析未定义。 我假设我将它们错误地传递给.call方法,但我没有找到其他传递方法 代码如下: import logger from './logger.utils'; import { spawn, ChildProcess } from 'child_process'; /** * This function runs a spawn command and

我正在编写一个现有模块,它生成一个子进程并执行一个命令

我将它作为一个类重新编写,但是当我运行代码时,我得到了一个错误,承诺被拒绝,解析未定义。 我假设我将它们错误地传递给
.call
方法,但我没有找到其他传递方法

代码如下:

import logger from './logger.utils';
import { spawn, ChildProcess } from 'child_process';

/**
 * This function runs a spawn command and rejects the promise if timed out
 * @param cmd - the command to execute
 * @param params - the command's parameters
 * @param timeoutMs - timeout in milliseconds
 * @param taskDescription - a text description of the task for logging
 */
export class SpawnTimeout {
  cmd: string;
  params: string[];
  finished: boolean;
  childProcess: ChildProcess;
  timeoutMs: number;
  timeout: NodeJS.Timeout;
  taskDescription: string;
  handlers: Object;

  constructor(
    cmd: string,
    params: string[],
    timeoutMs: number,
    taskDescription: string = 'no description specified'
  ) {
    this.finished = false;
    this.childProcess = spawn(cmd, params, {
      stdio: [process.stdin, process.stdout, process.stderr],
    });
    this.timeoutMs = timeoutMs;
    this.timeout = null;
    this.taskDescription = taskDescription;
    this.cmd = cmd;
    this.params = params;
  }
  exec() {
    return new Promise((resolve, reject) => {
      const handlers = {
        resolve,
        reject,
      };
      this.handlers = handlers;
      this.childProcess.once('error', this._onError.call(this.handlers));
      this.childProcess.once('exit', this._onExit.call(this.handlers));
      this.timeout = setTimeout(this._setTimeout, this.timeoutMs);
    });
  }
  _onError(err: Error, handlers) {
    clearTimeout(this.timeout);
    const message = `spawn [${this.taskDescription}] ${this.cmd}, ${this.params} failed with error ${err}`;
    logger.error(message);
    handlers.reject(new Error(message));
  }

  _onExit(code: number, handlers) {
    this.finished = true;
    clearTimeout(this.timeout);
    logger.debug(`spawn [${this.taskDescription}] finished.code ${code}`);
    if (code == 0) {
      handlers.resolve(true);
    }
    // case of error, code !== 0
    const message = `spawn [${this.taskDescription}] cmd : ${this.cmd} ${this.params}. failed with code ${code}`;
    logger.error(message);
    handlers.reject(new Error(message));
  }

  _setTimeout() {
    if (!this.finished) {
      logger.warn(
        `spawn [${this.taskDescription}] - timeout. cmd : ${this.cmd}, ${this.params}`
      );
      this.childProcess.kill();
    }
  }
}
调用
处理程序.resolve
处理程序.reject
时会生成错误


请告知我如何解决此问题?或者,即使这样的实现是一种良好的实践。

调用
立即调用函数,第一个参数是调用函数的
上下文,在这种情况下它不会返回函数,并且一次将结果作为
的侦听器是不正确的

回调需要用函数包装以提供预期参数:

this.childProcess.once('error', err => this._onError(err, this.handlers))
this.childProcess.once('exit', code => this._onExit(code, this.handlers));

由于回调必须以这种方式更正
this
,因此可能没有必要将
this.handlers
传递给它们,因为它们内部已经有了这些处理程序。

您误用了“call”。它使用另一个上下文调用函数,而不是像您期望的那样返回包装器。这就是“bind”所做的,但它有另一个签名,在这里不起作用,因为错误参数应该放在前面。它应该是
this.childProcess.once('error',err=>this.\u onError(err,this.handlers))
@EstusFlask请发布一个答案,这解决了问题。