【问题标题】:Promise chaining and error handling承诺链和错误处理
【发布时间】:2015-07-03 17:59:39
【问题描述】:

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

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 客户端,毫无疑问。

谢谢!

【问题讨论】:

  • 见这里developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。这是一个关于函数的问题,而不是关于 Promise 的问题。
  • 这确实是一个关于promises @elclanrs 的问题。如果您想就详细信息向我们提供启发,请不要犹豫,添加内容丰富的答案。
  • 试试.then(client.incrAsync.bind(client, config.channel_name + ":ad_hits", "vdvd"))

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


【解决方案1】:

当你链接 Promise 时,你会使用前一个函数的结果调用链中的下一个函数。

但是,您正在调用直接返回承诺的函数。因此,除非调用该函数返回一个返回 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,而不是 Promises,如果你希望它们在最后由你的 .catch 块处理。

【讨论】:

  • 所以当我不需要使用之前承诺的解析数据时,我必须使用匿名函数,你说?
  • 如果你将不相关的函数链接在一起,你需要将它们包装在匿名函数中是的。它们是不相关的,因为它们不会对相同的数据进行操作。
  • 为了让它更清楚——返回 Promise 的函数不是更大链的一部分——所以它需要单独的错误处理。但是由于 Promise 的工作方式,如果你从一个函数返回一个 Promise,这个 Promise 就会被包含到它的父链中——所以现在它得到了错误处理!
  • 最后一个子问题!我们能否运行一个同步函数并在该匿名函数中只返回一个值并在后面的 Promise 中使用它?
  • 是的,返回值的函数与为该值返回立即解析的 Promise 相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
相关资源
最近更新 更多