我是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上下文中的代码说明将不胜感激!
答案 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回调比较。
希望这有帮助;)