Javascript 直接传递process.stdout.write与通过回调传递会产生不同的输出?

Javascript 直接传递process.stdout.write与通过回调传递会产生不同的输出?,javascript,node.js,Javascript,Node.js,我不太清楚为什么会发生这种情况,但我写了以下内容: const runScript = (cmd, args) => { return new Promise((res, rej) => { // spawn a new process const ls = spawn(cmd, args); ls.stdout.on("data", (data) => {process.stdout.write(data)}); ls.stderr.o

我不太清楚为什么会发生这种情况,但我写了以下内容:

const runScript = (cmd, args) => {
  return new Promise((res, rej) => {
    // spawn a new process
    const ls = spawn(cmd, args);

    ls.stdout.on("data", (data) => {process.stdout.write(data)});

    ls.stderr.on("data", (data) => {process.stderr.write(data)});

    ls.on("close", code => {
      console.log(`Command ${cmd} ${args} exited with code ${code}`);
      code === 0 ? res(code) : rej(code);
    });

    ls.on("error", code => {
      rej(code);
    });
  });
};
这个很好用。但我想我可以将(“数据”)事件处理程序上的
.on更改为直接传入write函数。所以我从

ls.stdout.on("data", (data) => {process.stdout.write(data)});


根据命令的不同,重构后的版本(直接传递
.write
)或EPIPE没有输出。我以为他们是一模一样的。这里到底发生了什么?我怀疑它与缓冲或
进程所指的内容有关

当您将
process.stdout.write
作为参数传递时,它读取
process.stdout.write
的值,并只传递指向
write
方法的函数指针。然后,当
ls.staout.on()
稍后调用该方法时,它没有绑定到
process.stdout
,并且不能正常工作

改为:

ls.stdout.on("data", process.stdout.write.bind(process.stdout));
并且,当调用它时,它将被正确地绑定到所需的对象

有关如何在函数内部控制此
的摘要,请参阅


作为一个更简单的示例,请参见以下内容:

class X {
    constructor(val) {
        this.val = val;
    }
    add(otherVal) {
       return this.val + otherVal;
    }
}

let x = new X(3);
let fn = x.add;
fn(5);               // doesn't work properly
可以正常工作的示例:

let x = new X(3);
x.add(5);       // obj.method() sets proper value of this to obj in the method
或者,如果要传递该方法:

let x = new X(3);
let fn = x.add;
fn.call(x, 5);   // fn.call(x) artificially sets this to x inside the method
或者这个:

let x = new X(3);
let fn = x.add.bind(x);  // creates stub function that calls method properly
fn(5);
这也不起作用,因为当调用
fn(5)
时,没有绑定到
x
对象,因此当函数运行时,
add()
方法中对
This
的引用将不会具有正确的
This
值,并且无法正常工作

当此代码执行
let fn=x.add
操作时,它会获得一个指向
add
方法的指针,但对
x
对象没有绑定。那会丢失的。然后,当您调用
fn(5)
时,由于Javascript中的
this
值是根据调用函数的方式设置的,因此这只是一个普通函数调用,因此
this
值被设置为
未定义的
(在严格模式下)或全局对象(在非严格模式下)。无论哪种情况,它都不是所需的
x
对象。要使其成为
x
对象,必须将其称为
x.fn()
,该
值必须手动设置一些其他方法,例如使用
.apply()
.call()
.bind()


在上面的例子中,由于您不控制函数的调用方(它被您不控制的其他代码调用),因此
.bind()
是一个合适的解决方案。

当您将
process.stdout.write
作为参数传递时,它读取
process.stdout.write
的值,并只将函数指针传递给
write
方法。然后,当
ls.staout.on()
稍后调用该方法时,它没有绑定到
process.stdout
,并且不能正常工作

改为:

ls.stdout.on("data", process.stdout.write.bind(process.stdout));
并且,当调用它时,它将被正确地绑定到所需的对象

有关如何在函数内部控制此
的摘要,请参阅


作为一个更简单的示例,请参见以下内容:

class X {
    constructor(val) {
        this.val = val;
    }
    add(otherVal) {
       return this.val + otherVal;
    }
}

let x = new X(3);
let fn = x.add;
fn(5);               // doesn't work properly
可以正常工作的示例:

let x = new X(3);
x.add(5);       // obj.method() sets proper value of this to obj in the method
或者,如果要传递该方法:

let x = new X(3);
let fn = x.add;
fn.call(x, 5);   // fn.call(x) artificially sets this to x inside the method
或者这个:

let x = new X(3);
let fn = x.add.bind(x);  // creates stub function that calls method properly
fn(5);
这也不起作用,因为当调用
fn(5)
时,没有绑定到
x
对象,因此当函数运行时,
add()
方法中对
This
的引用将不会具有正确的
This
值,并且无法正常工作

当此代码执行
let fn=x.add
操作时,它会获得一个指向
add
方法的指针,但对
x
对象没有绑定。那会丢失的。然后,当您调用
fn(5)
时,由于Javascript中的
this
值是根据调用函数的方式设置的,因此这只是一个普通函数调用,因此
this
值被设置为
未定义的
(在严格模式下)或全局对象(在非严格模式下)。无论哪种情况,它都不是所需的
x
对象。要使其成为
x
对象,必须将其称为
x.fn()
,该
值必须手动设置一些其他方法,例如使用
.apply()
.call()
.bind()


在上面的例子中,由于您不控制函数的调用方(它正被您不控制的其他代码调用),因此
.bind()
是一个合适的解决方案。

我希望,这个问题将对您有所帮助。它基于相同的概念。我希望这个问题能对你有所帮助。它基于相同的概念@rb612-这回答了你的问题吗?如果是这样,您可以通过单击答案左侧的复选标记在此处向社区指出这一点。这也将为您在stackoverflow上按照正确的程序赢得一些声誉积分。如果这没有回答您的问题,请说明您对问题的哪一部分仍然感到困惑。@rb612-这回答了您的问题吗?如果是这样,您可以通过单击答案左侧的复选标记在此处向社区指出这一点。这也将为您在stackoverflow上按照正确的程序赢得一些声誉积分。如果这没有回答你的问题,请评论一下你对问题的哪一部分仍然感到困惑。