Q promise链存在失误后的承诺链

时间:2015-10-30 17:01:36

标签: javascript node.js azure q

我有一个node.js脚本,用于打开Azure容器,在多个不同国家/地区截取页面,同时将它们流式传输到Azure容器。我遇到的问题是,如果我在流式传输过程中遇到错误,它会完成剩余的给定ID的屏幕截图,然后退出promise链。

因此,如果我在Id 211006遇到错误,它会完成所有屏幕截图,然后退出流。它不会继续下去。

我对promises如何工作以及它们如何捕获错误非常了解,但我的理解是,如果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();

1 个答案:

答案 0 :(得分:2)

只要允许错误返回链中,就会停止一系列承诺。这将promise状态设置为拒绝,并将在任何后续.then()处理程序中调用下一个错误处理程序,而不是已完成的处理程序。

如果您希望链继续,那么您需要捕获错误。捕获错误将导致承诺基础架构将其视为“已处理”,并且将再次履行承诺状态,并且它将继续执行已完成的处理程序。

承诺错误类似于例外。如果它们没有被处理,它们将中止处理直到第一个异常处理程序。如果使用异常处理程序处理它们,那么处理将在该异常处理程序之后正常继续。

在您的具体情况下,如果您希望继续使用chaing,则需要处理每种类型的行中的错误:

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()链接循环中所有promises并删除如此多重复代码并处理各个国家/地区错误的方法,以便链继续:

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