2016-09-27 2 views
0

Я новичок в Node js и задавался вопросом, может ли кто-нибудь помочь мне.Что действительно означает обратный вызов Winston?

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 было бы очень полезно!

+2

Я бы сказал, если вы не знаете, для чего вам нужен обратного вызова событий журнала, то вы, вероятно, не нужен обратным вызова событий журнала. –

ответ

0

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 и обратного вызова.

Надеется, что это помогло;)