[英]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.