异步钩子堆栈已损坏

时间:2020-03-11 18:02:21

标签: node.js express asynchronous

我遇到了这个奇怪的错误,无法跟踪它。

设置:节点V8.10.0,expressjs,mongodb

我不认为它是API端点的一部分,而是导入程序脚本。

您会看到我在这里遇到的错误:https://dpaste.org/zs2S

始终是

错误:异步钩子堆栈已损坏

以下是我正在运行的代码。其目的是使用 chokidar 来观看目录。 (以前使用过 fs.watch ,但由于认为这是fs错误而仍然得到它,因此更改为 chokidar ),并且在更改文件时,请使用csv2json获取文件并将其作为json对象返回。

一旦检索到该对象,请将其插入mongo,首先将其添加名称_Update作为新集合。删除当前的活动目录,然后重命名新的目录,删除_Update,从而使其生效。

我使用pm2运行该应用程序。它会运行一段时间,但始终会因上述错误而在某些时候崩溃。

//require the mongojs package to setup db connection
var mongojs = require("mongojs");
//require the csvtojson package to convert the CSV file
var csv = require("csvtojson");
require("log-timestamp");
const chokidar = require("chokidar");
var config = 
require("../../config/config").get(process.env.NODE_ENV);
var db = mongojs(config.database);

exports.import = function() {
  // Initialize watcher.
  const watcher = chokidar.watch(config.watchfolder, {
    ignored: /(^|[\/\\])\../, // ignore dotfiles
    persistent: true,
    awaitWriteFinish: true
  });

  // Something to use when events are received.
  const log = console.log.bind(console);

  watcher.on("change", path => {
    log(`File ${path} has been changed`);

    let requiredCollection = config.sources.find(o => o.csvFile === path);

    csv()
      .fromFile(path)
      .then(jsonArrObj => {
        if (requiredCollection.collectionName.includes("RiverLevels")) {
          for (var item in jsonArrObj) {
            if (jsonArrObj[item].Movement == "S") {
              jsonArrObj[item].Movement = "Steady";
            }
            if (jsonArrObj[item].Movement == "R") {
              jsonArrObj[item].Movement = "Rising";
            }
            if (jsonArrObj[item].Movement == "F") {
              jsonArrObj[item].Movement = "Falling";
            }
            if (jsonArrObj[item].PrimaryStation == "1") {
              db.collection("riverOverview").replaceOne(
                { StationName: jsonArrObj[item].StationName },
                jsonArrObj[item]
              );
              console.log("Primary Station updated into riverOverview");
            }
          }
        }

        //Create new collection with _update
        db.createCollection(
          requiredCollection.collectionName + "_Update",
          function(err) {
            //Insert data fulled from file
            db.collection(requiredCollection.collectionName + "_Update").insert(
              jsonArrObj,
              function(err, result) {
                if (err) {
                  console.log(err);
                }
                console.log(
                  requiredCollection.collectionName + "_Update added to mongo"
                );

                //Drop the current DB
                db.collection(requiredCollection.collectionName).drop(function(
                  err
                ) {
                  if (err) {
                    console.log(err);
                  }
                  console.log(
                    "Old " + requiredCollection.collectionName + " deleted."
                  );
                  //rename update DB to make it the live one.
                  db.collection(
                    requiredCollection.collectionName + "_Update"
                  ).rename(requiredCollection.collectionName, function(
                    err,
                    collection
                  ) {
                    if (err) {
                      console.log(err);
                    } else {
                      console.log("rename Results: " + collection.namespace);
                    }
                    console.log(
                      requiredCollection.collectionName +
                        "_Update renamed to: " +
                        requiredCollection.collectionName
                    );
                  });
                });
              }
            );
          }
        );
      });
  });
};

1 个答案:

答案 0 :(得分:0)

您的代码花费的时间太长,这意味着多个请求将填充async queue,直到无法处理为止。

最好的做法是使用timeout处理异常,并稍作延迟再试。

let time = 0; 

try {
    // Do your stuff
    if ( time > 0 ) {
        time -= 1000;
    }
}
catch (e) {
    time += 1000;
    setTimeout(() => {
        // Do your stuff
    }, time);
}

当然,这是一种解决方法。您应该尝试减少执行操作所需的时间。

另一件事:您正在使用Node.js8。版本8不在其最终维护时段之内,不再受支持。您应该考虑升级到版本12。升级到最新版本也可以解决上述异步问题,而无需使用解决方法。