2015-02-06 103 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}) 
     }) 
}