【问题标题】:TypeError: done is not a function when connecting mongodb to app.js (not passport)TypeError:将mongodb连接到app.js(不是护照)时,完成不是一个函数
【发布时间】:2017-11-22 09:54:13
【问题描述】:

我正在关注terlici.com 上关于将 MongoDB 连接到 Web 应用程序的其余部分的教程。

我配置了一个db.js 文件,其内容如下:

DB.JS:

const MongoClient = require('mongodb').MongoClient;

const state = {
  db: null
}

exports.connect = (url, done) => {
  if (state.db) return done();

MongoClient.connect(url, (err, db) => {
  if (err) return done(err);
  state.db = db;
  done();
  });
}

exports.get = () => {
  return state.db;
}

exports.close = (done) => {
  if (state.db) {
    state.db.close((err, result) => {
    state.db = null;
    state.mode = null;
    done(err);
  })
  }
}

然后我在我的app.js 文件中调用db.connect(),如下所示:

APP.JS:

app.use((req, res, next) => {

db.connect('mongodb-url-goes-here', (e) => {
  if (e) return next(e);

  next();
});

// cleanup
req.on('end', () => { db.close(); });

});

db.js 中触发exports.close 警告的req.on('end'..... 行。

我假设 done 作为回调传入,所以我不确定它为什么返回错误消息。

另外,我假设我的代码中返回错误消息的行很有用,因此它会关闭未使用的数据库连接。首先这样做是否合适?

谢谢。

【问题讨论】:

    标签: node.js mongodb express


    【解决方案1】:

    您的 exports.close = (done) => {...} 函数需要一个 done 回调传递给它。

    但是,您没有在这一行中传递该回调:

    req.on('end', () => { db.close(); });
    

    您可以修改关闭函数,使回调是可选的:

    exports.close = (done) => {
      done = done || function() {};   // make sure there's always a callback here
      if (state.db) {
        state.db.close((err, result) => {
          state.db = null;
          state.mode = null;
          done(err);
      })
      }
    }
    

    我假设 done 是作为回调传入的,所以我不确定它为什么返回错误消息。

    您正在其他地方传递一个回调(例如 .connect()),但这里不是 db.close()

    另外,我假设我的代码中返回错误消息的行很有用,因此它会关闭未使用的数据库连接。首先这样做是否合适?

    是的,将 err 值传递给完成回调是传达异步错误值的典型方式。

    【讨论】:

    • 愚蠢的问题:要使用回调代替done,像(err) => {if (err) throw err }); 这样的东西是否合适?我不完全确定在这种情况下回调的目的是什么,tbh。
    • @JonathanBechtel - 不。异步回调中的每个throw 都不是一个好主意。无论如何,通常没有什么可以捕捉或处理throw。真正取决于您自己的编码逻辑来决定对来自db.close() 的错误应该做什么。可能您至少想记录具体错误是什么,以便您可以看到它的发生并可能调查原因。如果数据库无法正确关闭,您最终可能会耗尽某种资源,例如文件句柄。当关闭失败时,通常不需要任何其他操作。
    • @JonathanBechtel - 如果这回答了您的问题,那么您可以通过单击问题左侧的复选标记向社区表明这一点,并为自己在 stackoverflow 上遵循正确的程序赢得一些声誉积分.
    猜你喜欢
    • 2020-12-22
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 2017-01-16
    • 2019-08-05
    • 2017-06-12
    • 2018-04-28
    • 1970-01-01
    相关资源
    最近更新 更多