将日志功能传递给Promise

时间:2017-09-24 09:40:13

标签: javascript es6-promise

对于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>

我做错了什么?

2 个答案:

答案 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.assignoptsnull({而不是导致错误),undefined会忽略它。

使用Stage 3 proposalObject.assign可以使用传播:

  opts = {...defaultOpts, ...opts};

目前的形式,opts nullundefined也可以。但同样,传播属性目前只是第3阶段。

答案 1 :(得分:0)

您尚未在此处指定,但您可能会将spawnPromise opts调用opts作为您在顶部定义的opts.log之外的其他内容<或者在函数调用中根本不传递给该参数,这将使其未定义。

当{{1}}不是函数时,独立模块抛出特定错误或以其他显式方式处理它可能是个好主意。