Q 在 .then 成功回调中拒绝承诺

Q Reject promise within .then success callback

我在节点应用程序中使用 kriskowal Q promise 库。 我有读取文件的代码,然后尝试将文件的一部分解析为 Javascript 日期对象(我在其他地方有类似的代码试图执行 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 回调中的承诺会很有用,因为它失败了。

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

这实际上包含在 Handling Errors.

部分的 q 文档中

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

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

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

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

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

异常将传播到 promise 的接收者。

至于你的代码:

您在例外情况下得到保护,但如果您发现错误情况(不是由例外情况引起),您可以 return 在您的 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})
        })
}