在node.js中是否有办法在承诺中抛出错误?

Is it any way to throw errors inside promises in node.js?

本文关键字:出错 承诺 错误 node js 是否      更新时间:2023-09-26

js大师,

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

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

如果我取消注释"any errors here dies silent ",它就可以了。唯一的方法是在try/catch块内包装,但即使在那里,我也只能console.log(error)抛出新的错误不起作用。是否有任何方法运行带有自动失败选项的js ?Thx

promise捕获异常并将其转换为拒绝。因此,如果您在.then()处理程序中并且抛出异常,那么将生成与返回被拒绝的承诺相同的结果。这就是承诺的工作方式。

因此,为了使代码工作,您只需要返回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,当你已经有一个,你可以直接返回

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

你可以在这些参考文献中阅读更多关于承诺反模式的内容:

承诺反模式(Bluebird github)

承诺反模式(代码之道)

Promise Patterns &反模式