2015-02-06 2 views
1

Я использую библиотеку обещаний kriskowal Q в приложении узла. У меня есть код, который читает файл, а затем пытается проанализировать его часть в объект Date Javascript (у меня есть аналогичный код в других местах, где вы пытаетесь выполнить JSON.parse). В этих обстоятельствах я читал и лично считаю, что лучше всего использовать этот код в блоке try/catch, чтобы избежать и, возможно, фатальных сюрпризов. Вот некоторые реальный код смешивается с кодом псевдо:Q Отклонить обещание в пределах. Then callback

var getMonitorTimestamp = function() { 
    return readLogFile() 
     .then(
      function ok(contents) { 
       //regex to capture dates in format of: 09 Jan 2015 09:42:01 
       var regex = /[0-9]{2} [\w]{3} [0-9]{4} ([0-9]{2}:){2}[0-9]{2}/g; 
       var timestamp = contents.match(regex)[0]; 
       var date; 
       try { 
        date = new Date(timestamp); 
        return date; 
       } 
       //when I've caught the error here, how do I reject the promise? 
       //this will still return an error to the next success callback in the queue 
       catch(e) { 
        console.error(e); 
        return e; 
       } 

      }, 
      function err(e) { 
       console.error(e); 
       return new Error(); 
      } 
     ); 
}; 


exports.sendRes = function(req, res) { 
    getMonitorTimestamp() 
     .then(
      function yay(data) { 
       //don't want to send an error here 
       res.json({result: data}); 
      }, 
      function boo(e) { 
       res.status(500).json({error: e}); 
      } 
     ); 
} 

Как вы можете видеть, это было бы полезно, чтобы отклонить обещание в getMonitorTimstamp-> ОК обратного вызова, потому что это не удалось.

Есть ли способ сделать это в Q? Я ничего не нашел (пока). Или есть другой шаблон для обработки этого сценария?

ответ

3

Это фактически описано в q документах в разделе Handling Errors.

Вместо того, чтобы использовать стиль .then(success, fail), вы хотите связать обработчики, чтобы обработчик успеха был throw обработчику сбоев.

readLogFile() 
    .then(function yay(data) { 
    throw "Eek!"; 
    }) 
    .fail(function boo(e) { 
    res.status(500).json({error: e}); 
    }); 
+0

Хотя в реальной жизни никогда не бросайте струны: D –

+0

Виновен: P хотел сохранить пример как можно меньше! – Interrobang

0

На самом деле вам не нужно ловить исключения в ваших then функций, если вы используете эту конструкцию (как описано в Q documentation):

function a() { 
    return methodThatReturnsAPromise().then(function() { 
    // Exceptions can happen here 
    }) 
} 

a() 
    .then(function() { /* Success */ }) 
    .catch(function (err) { /* Error */ }) 

Исключения будут распространяться на получатель обещания.

Что касается вашего кода:

Вы покрыты за исключение, но если вы нашли состояние ошибки (не вызван исключением) вы можете вернуть новое отклоненное обещание в вашей readLogFile().then(... функции:

var getMonitorTimestamp = function() { 
    return readLogFile() 
    .then(function (contents) { 
     if (<check errors here>) { 
      // Found the error condition 
      return Q.reject(‘Failed here’) 
     } else { 
      // Return the normal result 
      ... 
      return date 
     } 
    }) 
} 

И оставить один catch положение на верхнем уровне кода:

exports.sendRes = function(req, res) { 
    getMonitorTimestamp() 
     .then(function (data) { 
      res.json({result: data}) 
     }) 
     .catch(function (e) { 
      res.status(500).json({error: e}) 
     }) 
} 
Смежные вопросы