繁体   English   中英

直接传递 process.stdout.write 与通过回调传递不同的 output?

[英]Passing process.stdout.write directly vs through callback gives different output?

我不太确定为什么会这样,但是我写了以下内容:

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("data")事件处理程序更改为直接传入 write function 。 所以我从

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

ls.stdout.on("data", process.stdout.write);

根据命令,我要么没有 output 重构版本(直接传递.write )或 EPIPE。 我以为他们完全一样。 这里到底发生了什么? 我怀疑它与缓冲或所指的process有关。

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

相反,改为:

ls.stdout.on("data", process.stdout.write.bind(process.stdout));

并且,当它被调用时,它将正确绑定到所需的 object。

请参阅如何在 function 调用中进行设置,以了解如何在this中对其进行控制。


作为一个更简单的示例,请参见:

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 object 所以当 function 运行时,在add()方法中对this的引用不会有正确的this值,它会赢不能正常工作。

当这段代码确实let fn = x.add时,它会获得一个指向add方法的指针,但没有绑定到x object。 那会丢失。 Then, when you call fn(5) , since the this value in Javascript is set according to how a function is called, this is just an ordinary function call so the this value is set to undefined (in strict mode) or the global object (当不处于严格模式时)。 无论哪种情况,它都不是所需的x object。 要使其成为x object,必须将其调用为x.fn()this值必须人为设置其他方法,例如使用.apply() 、 .call( .call().bind()

在上述情况下,由于您不控制 function 的调用者(它被您无法控制的其他代码调用),因此.bind()是一个合适的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM