承诺链接和错误处理

时间:2015-04-24 23:35:00

标签: javascript node.js error-handling promise bluebird

我正在尝试理解链接和错误处理承诺。在这里,我有一些链接的承诺。

return ad_fetcher.getAds(live_rail_url, ad_time, req.sessionID)
        .spread(generator.playlist_manipulate) // returns Promise.resolve([data, anotherData])
        .then(client.incrAsync(config.channel_name + ":ad_hits", "vdvd")) // FOCUS HERE
        .then(function() {
            console.log("AD FETCHED AND PLAYLIST GENERATED.");
            res.send(generator.generate_regular(config.default_bitrate));
            })
        .catch(function(err) {
            console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
            console.log("!!! AD FETCHER - THERE WAS AN ERROR:!!!!!!!!!!!");
            client.sadd(config.channel_name + ":ad_errors", err);
            client.incr(config.channel_name + ":ad_errors:count");
            console.log(err);
            console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
            res.send(generator.generate_regular(config.default_bitrate));
    });

现在在client.incrAsync(config.channel_name + ":ad_hits", "vdvd")行,我打算写错语法,看看.catch是否发现了错误。但是当我运行它时,我得到了这个:

  

未处理的拒绝错误:ERR错误的'incr'参数数量   命令

但是当我改变对这个承诺的使用时:

.
.
    .then(function() {
        return client.incrAsync(config.channel_name + ":ad_hits", "vdvd");
    })
.
.

错误很好。它不再“未处理”了。

我不明白这种行为。 incrAsync不会返回一个承诺,因此它的错误应该被链末尾的.catch捕获?

注意:我毫无疑问地宣传了redis客户端。

谢谢!

1 个答案:

答案 0 :(得分:3)

链接promises时,使用上一个函数的结果调用链中的下一个函数。

但是,您正在调用直接返回承诺的函数。因此,除非调用该函数返回一个返回Promise的函数,否则你没有正确链接。

所以其中任何一个都可行:

.spread(generator.playlist_manipulate) // returns Promise.resolve([data, anotherData])
.then(client.incrAsync) // this function will receive [data, anotherData]

或者,正如您在问题中使用的那样,匿名函数:

.spread(generator.playlist_manipulate) // returns Promise.resolve([data, anotherData])
.then(function() { // this function receives [data, anotherData] but throws it away
    // this Promise is "subsumed" by the Promise chain. The outer Promise BECOMES this Promise
    return client.incrAsync(config.channel_name + ":ad_hits", "vdvd");
})

因为否则,你所写的基本上是这样的:

.then(function)
.then(Promise)
.then(function)

但是如果您希望最后由.then块处理它们,则需要将函数传递给.catch,而不是Promise。