Promise 链和错误处理
Promise chaining and error handling
我正在尝试理解使用 promises 的链接和错误处理。在这里,我有一些承诺。
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
捕获。但是当我 运行 这个时,我得到这个:
Unhandled rejection Error: ERR wrong number of arguments for 'incr'
command
但是当我将该承诺的用法更改为:
.
.
.then(function() {
return client.incrAsync(config.channel_name + ":ad_hits", "vdvd");
})
.
.
错误抓得很好。已经不是"unhandled"了。
我不明白这种行为。 incrAsync
return 不是一个承诺,所以它的错误应该被链末端的 .catch
捕获吗?
注意:我承诺了redis客户端,毫无疑问。
谢谢!
当您链接承诺时,您会使用前一个函数的结果调用链中的下一个函数。
但是,您正在调用 returns 直接承诺的函数。因此,除非 调用 该函数 returns 一个 returns 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)
但是如果您希望函数在最后由 .catch
块处理,则需要将函数传递给 .then
,而不是 Promises。
我正在尝试理解使用 promises 的链接和错误处理。在这里,我有一些承诺。
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
捕获。但是当我 运行 这个时,我得到这个:
Unhandled rejection Error: ERR wrong number of arguments for 'incr' command
但是当我将该承诺的用法更改为:
.
.
.then(function() {
return client.incrAsync(config.channel_name + ":ad_hits", "vdvd");
})
.
.
错误抓得很好。已经不是"unhandled"了。
我不明白这种行为。 incrAsync
return 不是一个承诺,所以它的错误应该被链末端的 .catch
捕获吗?
注意:我承诺了redis客户端,毫无疑问。
谢谢!
当您链接承诺时,您会使用前一个函数的结果调用链中的下一个函数。
但是,您正在调用 returns 直接承诺的函数。因此,除非 调用 该函数 returns 一个 returns 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)
但是如果您希望函数在最后由 .catch
块处理,则需要将函数传递给 .then
,而不是 Promises。