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上按照正确的程序赢得一些声誉积分。如果这没有回答你的问题,请评论一下你对问题的哪一部分仍然感到困惑。