Node.js& MongoDB:为什么db对象未定义?

时间:2016-09-24 20:02:50

标签: javascript node.js mongodb

我正在使用Node.js,Hapi和MongoDB Native Driver(node-mongodb-native

我想在db.js的处理程序中从server.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
  }
})

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

1 个答案:

答案 0 :(得分:0)

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

要使其有效,请等到Promise得到解决:

'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 therethere