Winston позволяет передавать в функции обратного вызова, который выполняется, когда все транспорты вырублено
Это означает, что если у вас есть регистратор, который обрабатывает более одного транспорт (например, консоль и файл), обратный вызов будет выполнен только после того, как сообщения будут записаны на всех из них (в данном случае на консоли и в файле).
Операция ввода-вывода в файле всегда занимает больше времени, чем просто вывод сообщения на консоль. 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!');
}
Sure ... Вы вероятно, не будет определять задачи таким образом, но просто для того, чтобы показать один способ, которым вы могли бы запускать все задачи параллельно, и ждать, пока все будут записаны для продолжения других задач.
Просто объяснить пример кода:
const tasks
является массивом функций, где каждый из них принимает функцию x
в качестве параметра, сначала выполняет задачу под рукой, в этом случае простой console.log('task1');
затем выполняет функция, полученные в качестве параметра, x();
функция передается в качестве параметра для каждой из этих функций в массиве является () => winston.debug('CHILL WINSTON!',`logging task${++taskID}`, waitForIt)
waitForIt
, третий параметр в этом winston.debug
call, является фактическим обратным вызовом (обратный вызов 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 и обратного вызова.
Надеется, что это помогло;)
Я бы сказал, если вы не знаете, для чего вам нужен обратного вызова событий журнала, то вы, вероятно, не нужен обратным вызова событий журнала. –