Q拒绝承诺。然后成功回调

时间:2015-02-06 22:18:08

标签: node.js promise q

我在节点应用中使用kriskowal Q promise库。 我有代码读取文件,然后尝试将其中的一部分解析为Javascript Date对象(我在尝试执行JSON.parse的其他地方有类似的代码)。在这些情况下,我已阅读并个人认为最佳做法是将该代码包装在try / catch块中以避免并可能导致致命的意外。这里有一些与伪代码混合的真实代码:

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-> ok回调中的promise是有用的,因为它失败了。

Q中有没有办法做到这一点?我还没找到任何东西。或者处理这种情况有不同的模式吗?

2 个答案:

答案 0 :(得分:4)

这实际上已在Handling Errors部分的q文档中介绍。

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

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

答案 1 :(得分:0)

实际上,如果您使用此构造(如Q documentation中所述),则不需要在then函数中捕获异常:

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