【问题标题】:How can i break my promise chain in certain reject cases在某些拒绝案例中,我如何打破我的承诺链
【发布时间】:2019-05-17 19:53:45
【问题描述】:

我有一个承诺链,其中某些事情发生在 resolve 和不同的事情发生在拒绝,但有时我想跳过所有以下 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)});

在第一个 then 如果代码进入拒绝案例,我想跳过所有剩余的 then。然而它并没有,因此所有随后的事情都会发生并且都失败了。唯一应该继续的拒绝是在第三次我确实想要返回承诺时。

【问题讨论】:

标签: javascript node.js promise chain


【解决方案1】:

一般来说,您的问题是有些错误是致命的,有些则不是。您希望致命错误一直下降到底部,但非致命错误要按顺序处理。

将所有“致命”错误保留在顶层,并将非致命错误嵌套在 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 以获取与您的非常相似的一个很好的小示例。

【讨论】:

    猜你喜欢
    • 2019-11-25
    • 2017-11-23
    • 2014-01-09
    • 2018-02-11
    • 2020-02-23
    • 2013-09-16
    • 2017-07-16
    • 1970-01-01
    相关资源
    最近更新 更多