在某些拒绝情况下,我如何打破承诺链

时间:2018-12-17 12:34:29

标签: javascript node.js promise chain

我有一连串的承诺,其中某些事情发生在解决上,而其他事情发生在拒绝上,但是有时我想跳过以下所有then语句。

我的代码如下

await req.reduce((promise, audit) => {
    let globalData;
  return promise.then(_ => this.add(audit)
      .then((data)=> {
                          globalData = data; console.log('1'); 
                          return dropbox_functions.createFolder(data.ui, data)
                     }, 
           (error)=> {
                          failed.push({audit: audit, error: 'There was an error adding this case to the database'}); 
                          console.log('1.1'); i = i + 1; socket.emit('bulkAddUpdate', i/arrLen); 
                          throw new Error('There was an error adding this case to the database');
                     })
       .then((data)=>{
                         console.log('2');
                         return dropbox_functions.checkScannerFolderExists(audit.scanner_ui)
                     },
            (error)=>{
                         console.log('2.1');issues.push({audit: globalData, error: 'There was an error creating the case folder in dropbox'}); 
                         i = i + 1;socket.emit('bulkAddUpdate', i/arrLen); 
                         throw new Error('There was an error creating the case folder in dropbox');
                     })
       .then((data)=>{
                         console.log('3');
                         return dropbox_functions.moveFolder(audit.scanner_ui, globalData.ui)},
            (error)=>{
                         console.log('3.1');issues.push({audit: globalData, error: 'No data folder was found so an empty one was created'}); 
                         return dropbox_functions.createDataFolder(globalData.ui)
                     })
       .then(()=>    {
                         console.log('4');
                         success.push({audit:globalData}); 
                         i = i + 1;socket.emit('bulkAddUpdate', i/arrLen);},
          (error)=> {
                         issues.push({audit: globalData, error: 'Scanner folder found but items not moved'});console.log('4.1');
                    })
      .catch(function(error){
              console.log(error)
            })
    );
  }, Promise.resolve()).catch(error => {console.log(error)});

在第一个代码中,如果代码进入拒绝的情况,我想跳过所有其余的代码。但是,它没有发生,因此所有后续操作都将发生并且都将失败。唯一应该继续前进的拒绝是在第三次,当我确实想返回承诺时。

1 个答案:

答案 0 :(得分:0)

通常,您的问题是某些错误是致命的,有些不是致命的。您希望致命错误一路跌到谷底,但非致命错误要按顺序处理。

将所有“致命”错误保留在顶层,然后将非致命错误嵌套在then块内。我还建议从不使用“ then(fn,fn)”格式-始终明确指定渔获。

示例:

return fnA().then(dataA => {
    return fnB(dataA).catch(error => {
        console.log("fnB got a non-fatal error, I'm fixing it.");
        return fnFixB();
    });
})
.then(dataB => fnC())
.then(dataC => {
    return fnD(dataC).catch(error => {
        console.log("fnD didn't work, I'm fixing it.");
        return fnFixD();
    });
}).catch(error => {
    console.log("Sorry: one of fnA, fnFixB, fnC, or fnFixD must have broken.");
});

在此示例中,如果fnAfnC拒绝,那么您将跌至最低;但是fnBfnD会产生错误,可以从中恢复(尽管如果修复fnFixBfnFixD失败,您也将跌入谷底)。

此外,我建议您将代码分成较小的方法以提高可读性:请查看文章Error handling in long Promise chains,以获取一个与您的示例非常相似的小例子。