【问题标题】:Is it any way to throw errors inside promises in node.js?有没有办法在 node.js 中的 Promise 中抛出错误?
【发布时间】:2015-09-22 01:38:03
【问题描述】:

js 大师,

我正在用 nodejs(实际上是 iojs)编写一个解析器,并且我有一个典型的用 Promise 处理的厄运回调金字塔。花费我 70% 时间的问题是在 Promise 中查找错误。

    function parseHomeData(home, web) {
      var deferred = Q.defer();
      var homepage = web.url(home).then(function () {
// any error here dies silently
        parser.getHomeInfo(homepage).then(function (parsedHome) {
            console.log(parsedHome);
            deferred.resolve(parsedHome);

        }, function (err) {
            console.log(err);
            throw new Error(err);
        });
    }, function (err) {
        console.log(err);
    });
    return deferred.promise;
};

如果我取消注释“这里的任何错误都会默默地消失”,它会这样做。唯一的方法是包装在 try/catch 块中,但即使在那里我也只能 console.log(error) throw new Error 不起作用。有什么方法可以使用自动失败选项运行 iojs? 谢谢

【问题讨论】:

  • 谢谢,以前从未听说过。会看看。谢谢回答

标签: javascript node.js debugging


【解决方案1】:

Promises 捕获异常并将其转化为拒绝。因此,如果您在 .then() 处理程序中并抛出异常,则会产生与返回被拒绝的承诺相同的结果。这就是 Promise 的工作原理。

因此,要使您的代码正常工作,您只需返回 web.url() 正在创建的实际承诺。这也将消除您在不必要地创建承诺的地方的一些反模式。

function parseHomeData(home, web) {
    return web.url(home).then(function () {
        // any exception error here becomes the rejected promise
        return parser.getHomeInfo(homepage).then(function (parsedHome) {
            console.log(parsedHome);
            return parsedHome;
        }, function (err) {
            // this handler is only needed if you need the console.log(err) here
            console.log(err);
            throw new Error(err);
        });
    }, function (err) {
        // this handler is only needed if you need the console.log(err) here
        console.log(err);
        throw err;
    });
};

事实上,如果没有console.log() 语句,代码可能都会崩溃:

function parseHomeData(home, web) {
    return web.url(home).then(parser.getHomeInfo.bind(parser));
}

这个代码块结合了几个东西:

  1. 返回web.url() 承诺,因此如果它因任何原因被拒绝(例如在您的.then() 处理程序中抛出,它将作为您的parseHomeData() 函数的拒绝承诺返回。

  2. 当您已经拥有一个可以返回的 Q Promise 时,无需创建自己的 Q Promise。

  3. 一旦你实现了上面的项目 1) 和 2),那么你就可以在 .then() 处理程序中返回或抛出,而不是 resolve()reject()

您可以在这些参考资料中阅读更多关于 Promise 反模式的信息:

Promise Anti-patterns (Bluebird github)

Promise Anti-patterns (Tao of Code)

Promise Patterns & Anti-Patterns

【讨论】:

  • 非常感谢。期待代码,但如果你当然有时间,如果你能写更多关于 anipatterns 的内容 - 我喜欢写得很好:-)
  • 谢谢你的时间,jfriend。
  • @Svitlana - 我的问题中添加了几个反模式引用。
  • @Svitlana - 我添加了一个更短的答案版本。
  • 谢谢,现在可以使用了。您在代码中犯了一个小错误,但我得到:[ReferenceError: homepage is not defined] :-)
猜你喜欢
  • 1970-01-01
  • 2019-05-17
  • 2020-05-03
  • 2017-11-23
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 2011-10-13
相关资源
最近更新 更多