Winston 回调实际上是什么意思?

What does Winston callback actually mean?

我是 Node js 的初学者,想知道是否有人可以帮助我。

Winston 允许您传递一个回调,该回调在所有传输都已记录后执行 - 有人可以解释这意味着什么吗,因为我对回调和 Winston 的上下文有点迷茫?

来自 https://www.npmjs.com/package/winston#events-and-callbacks-in-winston 我看到了一个这样的例子:

  logger.info('CHILL WINSTON!', { seriously: true }, function (err, level, msg, meta) {
    // [msg] and [meta] have now been logged at [level] to **every** transport. 
  });

太好了...但是我的程序中有几个 logger.info,我想知道我应该在回调中放入什么?另外,我是否需要为每个 logger.info 执行此操作 - 或者我可以将所有日志放入一个函数中吗?

我想将所有日志调用添加到一个数组中,然后使用 async.parallel 让它们同时被记录?好主意还是坏主意?

主要目的是在我的程序继续执行其他任务之前记录所有内容。

非常感谢在回调和 winston 上下文中解释以上代码!

Winston allows you to pass in a callback which is executed when all transports have been logged

这意味着,如果您有一个处理多个传输(例如,控制台和文件)的记录器,则只有在消息被记录到所有这些传输(在这种情况下,在控制台和文件)。

对文件的 I/O 操作总是比仅在控制台上输出一条消息花费更长的时间。 Winston 确保回调将被触发,不是在第一个传输记录结束时,而是在最后一个(即花费时间最长的那个)结束时。

您不需要为每个 logger.info 使用回调,但在这种情况下,它可以帮助您确保在继续其他任务之前已记录所有内容:

var winston = require('winston');
winston.add(winston.transports.File, { filename: './somefile.log' });
winston.level = 'debug';

const tasks = [x => {console.log('task1');x();},x => {console.log('task2');x();},x => {console.log('task3');x()}];

let taskID = 0;
let complete = 0;
tasks.forEach(task => {
    task(() => winston.debug('CHILL WINSTON!', `logging task${++taskID}`, waitForIt));
});

function waitForIt() {
    // Executed every time a logger has logged all of its transports 
    if (++complete===tasks.length) nowGo();
};

function nowGo() {
    // Now all loggers have logged all of its transports
    winston.log('debug', 'All tasks complete. Moving on!');
}

当然...您可能不会以这种方式定义任务,只是为了展示一种您可以并行启动所有任务并等待所有内容都已记录以继续其他任务的方法。

只是为了解释示例代码:

const tasks是一个函数数组,其中每个接受一个函数x作为参数,首先执行手头的任务,在本例中是一个简单的console.log('task1');然后执行作为参数接收的函数,x();

作为参数传递给数组中每个函数的函数是 () => winston.debug('CHILL WINSTON!',`logging task${++taskID}`, waitForIt)

winston.debug 调用中的第三个参数 waitForIt 是实际回调(您查询的 winston 回调)。

现在,taskID 统计已启动的任务,而 complete 统计已完成记录的记录器。

作为异步,可以将它们作为 1、2、3 启动,但据我们所知,它们的记录器可能以 1、3、2 序列结束。但是因为它们一旦完成都会触发 waitForIt 回调,我们只计算有多少已经完成,然后在它们全部完成后调用 nowGo 函数。

比较
var winston = require('winston');
var logger = new winston.Logger({
    level:'debug',
    transports: [
        new (winston.transports.Console)(),
        new (winston.transports.File)({filename: './somefile.log'})
    ]
});

const tasks = [x => {console.log("task1");x();},x => {console.log("task2");x();},x => {console.log("task3");x()}];

let taskID = 0;
let complete = 0;
tasks.forEach(task => {
    task(() => logger.debug('CHILL WINSTON!', `logging task${++taskID}`, (taskID===tasks.length)? nowGo : null));
});

logger.on('logging', () => console.log(`# of complete loggers: ${++complete}`));

function nowGo() {
    // Stop listening to the logging event
    logger.removeAllListeners('logging');
    // Now all loggers have logged all of its transports
    logger.debug('All tasks complete. Moving on!');
}

在这种情况下,nowGo 将是回调,它只会添加到第三个 logger.debug 调用。但是,如果第二个记录器比第三个记录器完成得晚,它将继续而不等待第二个记录器完成记录。

在这样一个简单的示例中,它不会有什么不同,因为它们都同样快地完成,但我希望它足以理解这个概念。

同时,让我推荐这本书 Node.js Design Patterns by Mario Casciaro 以获得更高级的异步流排序模式。它还具有出色的 EventEmitter 与回调比较。

希望这对您有所帮助 ;)