Node.js&MongoDB:为什么数据库对象未定义

Node.js & MongoDB: why the db object is undefined?

本文关键字:为什么 数据库 对象 未定义 MongoDB js amp Node      更新时间:2023-09-26

我使用的是Node.js、Hapi和MongoDB Native Driver(Node MongoDB Native(

我想访问server.js中处理程序中db.js的get((方法返回的db对象。

db.js

'use strict'
const MongoClient = require('mongodb').MongoClient
let _db
function connect (url) {
  return MongoClient.connect(url, { server: { poolSize: 5 } })
  .then((db) => {
    _db = db
    console.log('Connected to MongoDB:', db.s.databaseName)
  })
  .catch((e) => {
    throw e
  })
}
function get () {
  return _db
}
function close () {
  if (_db) {
    console.log('Closing MongoDB connection.')
    _db.close()
  }
}
module.exports = {
  connect,
  close,
  get
}

server.js

'use strict'
const Hapi = require('hapi')
const Db = require('./db')
const _db = Db.get()
const server = new Hapi.Server()
server.connection({
  host: 'localhost',
  port: 8080
})
server.route({
  method: 'GET',
  path: '/',
  handler: (req, rep) => {
    console.log(_db) // _db is undefined
  }
})
Db.connect('mongodb://localhost:27017/test')
.then(() => {
  server.start((err) => {
    if (err) {
      throw err
    }
    console.log(`Server running at: ${server.info.uri}`)
  })
})
.catch((e) => {
  console.error(`${e.name}: ${e.message}`)
  return
})

问题是Db.get()返回undefined

现在考虑这个代码:

const Db = require('./db')
const server = new Hapi.Server()
...
server.route({
  method: 'GET',
  path: '/',
  handler: (req, rep) => {
    const _db = Db.get()
    console.log(_db) // the _db object exists
  }
})

我不明白为什么第一个代码在调用get((方法时返回undefined,并且应该将实例存储到_db中,以便在处理程序函数中访问。

在传递给Promise的then的函数中分配_db的值,该部分的执行将推迟到某个时间点,直到Promise得到解决。server.route是同步的。这意味着它很可能在承诺得到解决之前执行

要使其发挥作用,请等待承诺得到解决:

'use strict'
const MongoClient = require('mongodb').MongoClient
let _db
async function connect (url) {
  try {
    return await MongoClient.connect(url, { server: { poolSize: 5 } })
  } catch (error) {
    throw new Error('Could not connect to Mongo instance');
  }
}
async function get () {
  return _db ? _db : await connect();
}
async function close () {
  if (_db) {
    console.log('Closing MongoDB connection.')
    _db.close()
  }
}
module.exports = {
  connect,
  close,
  get
}

然后

'use strict'
const Hapi = require('hapi')
const Db = require('./db')
const _db = await Db.get()
const server = new Hapi.Server()
server.connection({
  host: 'localhost',
  port: 8080
})
server.route({
  method: 'GET',
  path: '/',
  handler: async (req, rep) => {
    const _db = await Db.get();
    console.log(_db) // _db will be guaranteed to be a valid object, otherwise an error will be thrown
  }
})
Db.connect('mongodb://localhost:27017/test')
.then(() => {
  server.start((err) => {
    if (err) {
      throw err
    }
    console.log(`Server running at: ${server.info.uri}`)
  })
})
.catch((e) => {
  console.error(`${e.name}: ${e.message}`)
  return
})

阅读更多关于async/await的信息。

相关文章: