我有一个node.js脚本,它打开一个Azure容器,在将页面流式传输到Azure容器的同时,对多个不同国家/地区的页面进行屏幕截图。我遇到的问题是,如果我在流媒体处理过程中遇到错误,它会完成给定id的剩余屏幕截图,然后退出承诺链。
因此,如果我在Id 211006
处遇到错误,它将完成所有屏幕截图,然后退出流。它不会继续。
我对promise的工作方式以及它们如何捕捉错误非常陌生,但我的理解是,如果211006
确实遇到错误,脚本将完成promise链,然后在运行.fin
之前向我显示任何错误——事实并非如此。
有人能帮忙吗?
AzureService.createContainer()
.then(function () {
return ScreenshotService.getAllCountriesOfId('308572');
})
.then(function () {
return ScreenshotService.getAllCountriesOfId('211006');
})
.then(function () {
return ScreenshotService.getAllCountriesOfId('131408');
})
.then(function () {
return ScreenshotService.getAllCountriesOfId('131409');
})
.then(function () {
return ScreenshotService.getAllCountriesOfId('789927');
})
.then(function () {
return ScreenshotService.getAllCountriesOfId('211007');
})
.then(function () {
return ScreenshotService.getAllCountriesOfId('833116');
})
// Upload Log file into Azure storage
.fin(function () {
AzureService.init({
container: config.azure.storage.msft.CONTAINER.LOG,
account: config.azure.storage.msft.ACCOUNT,
key: config.azure.storage.msft.ACCESS_KEY,
file: config.file.log,
isLogFile: true
});
log.info('Utility: Uploading log file [ %s ] to Azure storage container [ %s ]', AzureService.file, AzureService.container);
return AzureService.uploadLocalFileToStorage()
.then(function () {
return util.deleteFile({fileName: AzureService.file, isLogFile: true});
})
.fail(function (err) {
log.info(err);
})
.done();
})
.fail(function (err) {
log.info(err);
})
.done();
只要允许错误返回承诺链,就会停止承诺链。它将promise状态设置为rejected,并将调用任何后续.then()
处理程序中的下一个错误处理程序,而不是已完成的处理程序。
如果您希望链继续,那么您需要捕获错误。捕获错误将导致promise基础结构认为它"已处理",并且promise状态将再次得到满足,并且它将继续执行已满足的处理程序。
承诺错误类似于例外情况。如果不处理它们,它们将中止处理,直到出现第一个异常处理程序。如果它们是用异常处理程序处理的,那么在该异常处理程序之后,处理将正常继续。
在您的特定情况下,如果您想继续链接,您需要处理以下每种类型的行中的错误:
return ScreenshotService.getAllCountriesOfId('308572');
你可以这样做:
return ScreenshotService.getAllCountriesOfId('308572').then(null, function(err) {
console.log(err);
// error is now handled and processing will continue
});
由于您有很多重复的代码,您可能应该将代码更改为通过一组国家/地区ID进行迭代的代码,而不是一遍又一遍地复制代码行。
以下是一种使用.reduce()
将所有承诺链接到一个循环中的方法,可以消除如此多的重复代码并处理各个国家/地区的错误,从而使链接继续:
var countryIds = ['308572', '211006', '131408', '131409', '789927', '211007', '833116'];
countryIds.reduce(function(p, item) {
return p.then(function() {
return ScreenshotService.getAllCountriesOfId(item).then(null, function(err) {
console.log(err);
});
});
}, AzureService.createContainer())
// Upload Log file into Azure storage
.fin(function () {
... rest of your code continued here