仅在第二次api请求之后才访问Mongo

时间:2019-01-05 17:18:30

标签: javascript node.js mongodb express

我想用API URLS读取mongodb数据库。当我在浏览器中访问/ showdb时,仅在第二次刷新后才显示json。我如何第一次得到它?谢谢!

const express = require("express");
const app = express();

var mongo = require('mongodb');


var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";

var resultdb;

function readDB() {
    MongoClient.connect(url, function(err, db) {
      if (err) throw err;
      var dbo = db.db("simpledb");
      dbo.collection("simplecollection").find().toArray(function(err, result) {
        if (err) throw err;
        resultdb = result;
        db.close();
      });
    });

    return resultdb;
};

//handle normal file requests etc.
app.use(express.static(__dirname + "/"));

app.get('/showdb', function(req, res) {
    res.send(readDB());
});

app.listen(10008);
console.log("Server running on port: " + 10008);

3 个答案:

答案 0 :(得分:0)

这里发生的是,您在不等待数据库响应的情况下返回了resultdb。因此,为什么在发送res后更新由于您的变量而导致的第二次调用。请尝试以下

const url = "mongodb://localhost:27017/";
const mongoClient = new MongoClient(new Server(url, 27017));


async function readDB() {
    mongoClient.open(function(err, db) {
      if (err) throw err;
      var dbo = db.db("simpledb");
      const res = dbo.collection("simplecollection").find().toArray(function(err, result) {
        if (err) throw err;
        return result
      });
      mongoClient.close();
      return await res
    });
};

mongoClient.open(function(err, mongoClient) {
  var db1 = mongoClient.db("mydb");

  mongoClient.close();
});

此外,为每个任务创建连接也不是一个好习惯。

我建议创建一个单独的函数以在服务器启动时进行连接,然后在要执行数据库任务时只使用client.open()

答案 1 :(得分:0)

代码的问题在于,它不等待readDB()完成与Mongodb的任务,而返回的空值为resultdb,因为它刚刚被定义。

但是,当您一次调用它时,请求得到处理后,readDB()将从Mongodb接收到数据,并将其设置为resultdb。下次调用api时,您将在上一个api调用中处理结果,而不是新的api。

尝试一下-

app.get('/showdb', async function(req, res) {
  const result = await readDB(); // here we are waiting for the results to finish using await.
  res.send(result);
});

,您的readDB的功能为-

async function readDB() { // making using of async here.
    MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        const dbo = db.db('simpledb');
        dbo.collection('simplecollection').find().toArray(function(err, result) { 
            if (err) throw err;
            resultdb = result;
            return resultdb; // we can now return it.
            db.close();
        });
    });
};

注意:考虑到您使用的是支持异步的更新节点版本-等待

---更新----

您可以尝试--

app.get('/showdb', async function(req, res) {
    readDB(req, res);
});

function readDB(req, res) { // making using of async here.
    MongoClient.connect(url, function(err, db) {
        if (err){
            res.send(err);
            throw err;
        }
        const dbo = db.db('simpledb');
        dbo.collection('simplecollection').find().toArray(function(err, result) { 
            if (err){
                res.send(err);
                throw err;
            }
            res.send(result)
            db.close();
        });
    });
};

答案 2 :(得分:0)

您需要使用不能使用同步代码的回调。像这样:

app.get('/', (req, res) => {
  MongoClient.connect(url, (conn, err) => {
    conn.db('foo').collection('bar').find().toArray((err, result) => {
      res.send(result)
    })
  })
})

回调函数稍后执行,这就是为什么它们是回调函数。如果您想编写看起来更像同步代码的代码,请查看promise API并等待