【问题标题】:My Promise going into both then and catch我的承诺同时进入并抓住
【发布时间】:2019-05-07 09:36:03
【问题描述】:

我有一组嵌套的 Promise,如下所示。这里的预期行为是打印 1,然后打印 2,然后在 dropbox_functions.moveFolder('test', data.ui) 下调用回调。然而发生的事情是 1 被打印然后 2 被打印并且 2.1 被打印,所以 2 承诺进入thencatch。我不知道为什么。

dropbox_functions.createBatchFolder(data.ui)
        .then(function(response) {
          console.log('1')
          console.log(response)
          dropbox_functions.checkScannerFolderExists('test')  
            .then(function(response) {
              console.log('2')
              console.log(response)
              dropbox_functions.moveFolder('test', data.ui)
                .then(function(response) {
                  console.log(response)
                  callback(null, data)
                })
                .catch(function(error) {
                  console.log(error);
                  callback('Data not copied from scanner', data)
                });
            })
            .catch(function(error) {
                console.log('2.1')
                console.log(response)
                dropbox_functions.createDataFolder(data.ui)
                  .then(function(response) {                      
                    console.log(response)
                    callback('No scanned folder', data)
                  })
                  .catch(function(error) {
                    console.log(error);
                    callback('Data Folder not created', data)
                  });  
            });
            // callback(null, data)
        })
        .catch(function(error) {
          console.log('1.2')
          console.log(error)
          callback('Folder not created', data)
        });

【问题讨论】:

  • 你为什么要嵌套你的承诺?这就是避免回调地狱的承诺的全部意义
  • 这意味着dropbox_functions.moveFolder('test', data.ui) 产生了异常。与其使用console.log('2.1'),不如使用console.log('2.1', error),这样您就知道异常是什么了。
  • 您可以创建不同的 Promise 并调用 then 来解决每个 Promise 并使用 1 个 catch 来解决错误。这确实会导致不知道错误发生在哪里的问题,但在这种情况下,您可以切换到 async/await
  • dropbox_functions.moveFolder 是您出错的原因。要么功能不可用,要么data.ui不可用
  • 您设置其中一个捕获的方式充当了通过。所以它捕捉到一个错误,然后继续解决

标签: javascript node.js dropbox


【解决方案1】:

在执行console.log('2') 行之后,肯定会抛出一个错误。如果在 Promise 执行中抛出错误,下一个立即的 catch 块将捕获特定的错误。

              console.log('2')
              console.log(response) <-- Here 
              dropbox_functions.moveFolder('test', data.ui) <--- Here 
                .then(function(response) {
                  console.log(response)
                  callback(null, data)
                })
                .catch(function(error) { <-- or here
                  console.log(error);
                  callback('Data not copied from scanner', data)
                });

【讨论】:

  • movefolder 没有返回导致错误的承诺,我现在已经解决了这个问题,谢谢
【解决方案2】:

这不是答案,而是建议。承诺的全部意义在于您不必嵌套它们,而是可以chain 它们。这是通过简单地返回一个新的 Promise 作为提供给 then 的函数的返回值来完成的。然后,您可以在它之后链接另一个 then 语句来处理新解决的承诺。

dropbox_functions
  .createBatchFolder(data.ui)
  .then(function (response) { // response of createBatchFolder 
    console.log('1');
    console.log(response);
    return dropbox_functions.checkScannerFolderExists('test');
  })
  .then(function (response) { // response of checkScannerFolderExists
    console.log('2');
    console.log(response);
    return dropbox_functions.moveFolder('test', data.ui);
  })
  .then(function (response) { // response of moveFolder
    console.log(response);
    callback(null, data);
  })
  .catch(function (error) { // some error occurred
    console.error(error);
    callback(error, data);
  });

如果您需要针对特定​​错误采取措施,您可以检查错误的name 和/或description 属性,或通过调用toString() 将其转换为字符串。


此外,通过自己调用回调函数,您仍然可以将callback hell 引入您的程序。我建议改为返回一个承诺并使用它。如果上面的代码是你的函数的最后一个语句,你可以简单地从最后一个 then 语句返回一个已解决的承诺。

function yourFunction() {
  // ...
  return dropbox_functions
    .createBatchFolder(data.ui)
    // ...
    .then(function (response) { // response of moveFolder
      console.log(response);
      return Promise.resolve([null, data]);
    })
    .catch(function (error) { // some error occurred
      console.error(error);
      return Promise.reject([error, data]);
    });
}

如果它不是最后一条语句,只需将生成的承诺保存到一个变量中,然后在你做其他事情之后返回它。如果您所做的只是将其转发到Promise.reject(...),您甚至可以省略catch 语句(目前不是这种情况,因为您也添加了data)。这可以通过调用 yourFunction 的代码来处理。

【讨论】:

    猜你喜欢
    • 2016-10-25
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多