温斯顿的回调究竟意味着什么?

时间:2016-09-27 19:16:20

标签: javascript node.js callback winston

我是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上下文中的代码说明将不胜感激!

1 个答案:

答案 0 :(得分:0)

  

Winston允许您传入在记录所有传输时执行的回调

这意味着如果你有一个处理多个传输的记录器(例如,控制台和文件),只有在所有消息都被记录之后才会执行回调(在这种情况下,两者都是控制台和文件)。

文件上的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)

waitForIt调用中的第三个参数winston.debug是实际的回调(您询问过的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 vs回调比较。

希望这有帮助;)