2015-02-06 74 views
1

我在节点应用程序中使用kriskowal Q promise库。 我有代码读取一个文件,然后试图解析它的一部分到一个Javascript日期对象(我有类似的代码在其他地方试图做一个JSON.parse)。在这些情况下,我已经阅读并亲自感觉最好的做法是将这些代码包装在try/catch块中以避免和潜在的致命意外。下面是用伪代码混合一些实际的代码:Q拒绝承诺。然后成功回调

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

这实际上覆盖了Handling Errors下的q文档。

而不是使用.then(success, fail)样式,您需要链接您的处理程序,以允许成功处理程序throw到失败处理程序。

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

尽管在现实生活中不会丢字符串:D – 2015-02-06 23:17:53

+0

有罪:P想保持尽可能小的例子! – Interrobang 2015-02-06 23:54:42

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}) 
     }) 
}