为什么会收到“ UnhandledPromiseRejectionWarning”,这是什么意思?

时间:2019-07-16 05:51:39

标签: javascript node.js asynchronous synchronization

我正在尝试读写CSV文件,而我对javascript还是很陌生。我的代码对我来说似乎很有意义,但是我不确定为什么它没有运行。

app.post('/name=:name/available=:available/type=:type/subtype=:subtype/ip=:ip', (req, res) => {
  csvtojson().fromFile(csvFilePath).then((objects) => {
    objectsArray = objects;
    const newItem = {
      id: objectsArray.length + 1, 
      name: req.params.name,
      available: req.params.available
    };

    csvWriter.writeRecords(objectsArray).then( () => {
      console.log("Csv File Created!");
      console.log(objectsArray);
      res.json(objectsArray);
    });
   });
});

据我所知,我应该首先读取CSV文件,然后将内容保存在数组中,然后创建一个对象,然后将该对象写入CSV文件。但是我得到了以下错误:“ UnhandledPromiseRejectionWarning:错误:EBUSY:资源繁忙或锁定”,以及“ UnhandledPromiseRejectionWarning:未处理的Promise拒绝。此错误是由于在没有catch块的情况下抛出了异步函数而引起的,或者是因为不能使用.catch()处理。(拒绝ID:1)“

1 个答案:

答案 0 :(得分:0)

UnhandledPromiseRejectionWarning成为您的两个异步操作之一,遇到EBUSY错误,并且您没有针对该错误的错误处理程序。 node.js运行时发现承诺被拒绝,但是没有错误处理程序,并将其识别为可能的不适当编码情况(错误),因此发出警告。

在Javascript中,每个可以拒绝的promise操作都必须具有错误处理程序。可以使用.catch()try/catch(如果已完成await.then()的第二个参数)来完成承诺拒绝的错误处理程序。

您可以在代码中添加适当的错误处理程序,这将使您更加了解错误发生的位置,并摆脱UnhandledPromiseRejectionWarning

app.post('/name=:name/available=:available/type=:type/subtype=:subtype/ip=:ip', (req, res) => {
  csvtojson().fromFile(csvFilePath).then((objects) => {
    const newItem = {
      id: objects.length + 1, 
      name: req.params.name,
      available: req.params.available
    };

    return csvWriter.writeRecords(objects).then( () => {
      console.log("Csv File Created!");
      console.log(objects);
      res.json(objects);
    });
   }).catch(err => {
      console.log(err);
      res.sendStatus(500);
   });
});

如果出于调试目的,您想要单独记录第二个Promise拒绝,则可以执行以下操作:

app.post('/name=:name/available=:available/type=:type/subtype=:subtype/ip=:ip', (req, res) => {
  csvtojson().fromFile(csvFilePath).then((objects) => {
    const newItem = {
      id: objects.length + 1, 
      name: req.params.name,
      available: req.params.available
    };

    return csvWriter.writeRecords(objects).then( () => {
      console.log("Csv File Created!");
      console.log(objects);
      res.json(objects);
    }).catch(err => {
      console.log("csvWriter error", err);
      throw err;
    });
   }).catch(err => {
      console.log(err);
      res.sendStatus(500);
   });
});

在这种情况下,我返回了第二个promise,它将第二个promise链接到第一个promise,因此我们可以向第一个promise添加单个.catch()处理程序,它将捕获来自任何一个promise的错误。然后,错误处理程序发送500状态以完成请求处理程序。

我想EBUSY错误与读取csvFilePath表示的文件或csvWriter试图写入的文件有关。听起来这可能是文件排他性的问题,在打开该文件时可以进行独占访问,而不允许其他读取器/写入器访问。

如果看不到代码的更多上下文并理解文件可能具有多个读写器而导致某种竞争的情况,我们就无法真正解决该特定错误。


仅供参考,看来您应该摆脱objectsArray变量,而只需使用objects即可。 objectsArray不在此函数中本地声明。如果根本没有声明,那么它是一个隐式全局(这很糟糕)。如果在更高的范围内声明它,那么它是一个可能在每个都发出相同请求的用户之间共享的变量(非常糟糕的错误)。