对于Node库,我希望能够将日志函数传递给返回Promise的函数。默认情况下,记录器将为console.log
,但可能会被其他内容替换,具体取决于用例。
// define custom logger
const opts = {
log: console.log,
error: console.error
};
const spawnPromise = (cmd, args, opts) => {
return new Promise((resolve, reject) => {
const child = spawn(cmd, args, opts);
child.stdout.on('data', (data) => {
// use custom log function
opts.log(stringify(data));
});
child.stderr.on('data', (data) => {
// use custom error function
opts.error(stringify(data));
});
child.on('close', (code) => {
if (code === 0) {
resolve();
} else {
reject();
}
});
});
};
这会导致以下错误:
Uncaught Exception: test.js
TypeError: opts.log is not a function
Socket.<anonymous>
我做错了什么?
答案 0 :(得分:1)
opts
中的spawnPromise
不您在其上方声明的opts
,它是您为spawnPromise
声明的参数这里:
const spawnPromise = (cmd, args, opts) => {
// ------------------------------^^^^
该参数会影响模块全局。 spawnPromise
将使用您传递的内容,而不是全局模块。如果要使用全局模块,请更改其名称或参数。
也许(见<===
评论):
// define custom logger
const defaultOpts = { // <=== Change name
log: console.log,
error: console.error
};
const spawnPromise = (cmd, args, opts) => {
opts = Object.assign({}, defaultOpts, opts); // <=== Expand with defaults
return new Promise((resolve, reject) => {
const child = spawn(cmd, args, opts);
child.stdout.on('data', (data) => {
// use custom log function
opts.log(stringify(data));
});
child.stderr.on('data', (data) => {
// use custom error function
opts.error(stringify(data));
});
child.on('close', (code) => {
if (code === 0) {
resolve();
} else {
reject();
}
});
});
};
请注意,如果Object.assign
为opts
或null
({而不是导致错误),undefined
会忽略它。
使用Stage 3 proposal,Object.assign
可以使用传播:
opts = {...defaultOpts, ...opts};
目前的形式,opts
null
或undefined
也可以。但同样,传播属性目前只是第3阶段。
答案 1 :(得分:0)
您尚未在此处指定,但您可能会将spawnPromise
opts
调用opts
作为您在顶部定义的opts.log
之外的其他内容<或者在函数调用中根本不传递给该参数,这将使其未定义。
当{{1}}不是函数时,独立模块抛出特定错误或以其他显式方式处理它可能是个好主意。