2015-10-30 2 views
1

У меня есть скрипт node.js, который открывает контейнер Azure, снимает скриншоты страницы из разных стран и передает их в контейнер Azure. Проблема, с которой я столкнулась, - это если я столкнулся с ошибкой в ​​потоковом процессе, она завершает оставшиеся скриншоты для данного идентификатора, а затем выходит из цепочки обещаний.Q цепочка обещаний существует цепочка обещаний после ошибки

Так что, если я столкнулся с ошибкой на Id 211006, он завершает выполнение всех скриншотов, а затем выходит из потока. Это не продолжается.

Я очень новичок в том, как работают обещания и как они ловят ошибки, но я понимаю, что если, скажем, 211006 действительно встретит ошибку, скрипт завершит цепочку обещаний, а затем покажет мне какую-либо ошибку до работает .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(); 

ответ

2

Цепочка обещаний прекращается в любое время, когда ошибка возвращается в цепочку. Это заставляет условие обещания отклоняться и будет вызывать следующий обработчик ошибок в любых последующих обработчиках .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 
}); 

Поскольку у вас много повторяющегося кода, вы, вероятно, должны изменить свой код на то, что итерации через массив идентификаторов страны, а не просто копировать строки кода снова и снова.


Вот средство использования .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 
Смежные вопросы