gpt4 book ai didi

javascript - 直接传递 process.stdout.write 与通过回调给出不同的输出?

转载 作者:行者123 更新时间:2023-12-01 00:31:57 28 4
gpt4 key购买 nike

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

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") 事件处理程序以直接传递写入函数。所以我从

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

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

根据命令的不同,我要么得不到重构版本的输出(直接传递 .write),要么得到 EPIPE。我以为它们是完全一样的。这里究竟发生了什么?我怀疑它与缓冲或 process 所指的内容有关。

最佳答案

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

改为:

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

并且,当调用它时,它将正确绑定(bind)到所需的对象。

参见How this is set inside a function call有关如何操作的摘要 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)被调用时,没有绑定(bind)到 x对象,因此当函数运行时,对 this 的引用里面add()方法不会有正确的值 this并且它无法正常工作。

当此代码执行 let fn = x.add 时,它得到一个指向 add 的指针方法,但没有绑定(bind)到 x目的。那就迷路了。然后,当您调用fn(5)时,自 this Javascript 中的值是根据函数的调用方式设置的,这只是一个普通的函数调用,所以 this值设置为undefined (在严格模式下)或全局对象(不在严格模式下)。无论哪种情况,都不是所需的 x目的。使其成为x对象,它必须被称为 x.fn() this的值必须人为地设置一些其他方法,例如使用 .apply() , .call().bind()

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

关于javascript - 直接传递 process.stdout.write 与通过回调给出不同的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58461694/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com