Nodejs mongodb 重复执行问题

Nodejs mongodb 重复执行问题

var MongoClient = require(’./node_modules/mongodb’).MongoClient

var http = require(‘http’); var db = null;

MongoClient.connect(‘mongodb://127.0.0.1:27017/lbs’, function(err, database) {

if(err) throw  err;
db = database;
server.listen(1234);

})

var server =http.createServer(function(req,res){ //console.log(db); db.eval(‘locate(118,24)’,function(err,xx){ console.log(“123”+xx); //res.write(xx); res.end(xx);

});

});

 console.log("123"+xx); 会打印两次,怎么回事

2 回复

在Node.js中使用MongoDB时,如果遇到重复执行的问题,通常是因为数据库连接或查询操作没有正确处理异步性。在你的例子中,db.eval方法可能被多次调用,导致结果被打印两次。

示例代码及解释

让我们首先修复代码中的问题,并确保数据库操作只执行一次。以下是修改后的代码:

var MongoClient = require('mongodb').MongoClient;
var http = require('http');

// 创建一个全局变量来存储数据库连接
var db = null;

// 连接到MongoDB数据库
MongoClient.connect('mongodb://127.0.0.1:27017/lbs', function(err, database) {
    if (err) throw err;
    db = database;
    
    // 启动HTTP服务器
    var server = http.createServer(function(req, res) {
        // 确保db对象已初始化
        if (!db) {
            res.writeHead(500, {'Content-Type': 'text/plain'});
            res.end('Database connection not established.');
            return;
        }

        // 执行MongoDB的eval命令
        db.eval('locate(118,24)', function(err, xx) {
            if (err) {
                res.writeHead(500, {'Content-Type': 'text/plain'});
                res.end('Error executing eval command.');
                return;
            }
            
            // 打印结果并发送给客户端
            console.log("Result: " + xx);
            res.end("Result: " + xx);
        });
    });

    server.listen(1234, function() {
        console.log('Server listening on port 1234');
    });
});

// 处理未捕获的异常
process.on('uncaughtException', function(err) {
    console.error('Uncaught Exception:', err);
});

解释

  1. 全局数据库连接

    • db声明为全局变量,确保在整个应用生命周期内只有一个数据库连接。
  2. 确保数据库连接

    • 在创建HTTP服务器之前,确保数据库连接已经成功建立。如果连接失败,则返回错误信息。
  3. 处理异步操作

    • db.eval是一个异步函数,需要正确处理回调。确保在回调中处理所有可能出现的错误。
  4. 避免重复执行

    • 如果需要确保某个操作只执行一次,可以在执行前添加适当的检查逻辑,例如在全局变量中设置一个标志位。

通过这种方式,你可以避免由于异步操作引起的重复执行问题,并确保数据库连接和操作的正确性。


在你的代码中,db.eval('locate(118,24)', function(err, xx) 这段代码会在每次请求时被执行,因此每次请求都会调用 console.log("123" + xx);。如果你看到 console.log("123" + xx); 打印了两次,可能是因为请求被发送了两次。

为了确保每个请求只执行一次 MongoDB 操作,并且避免重复执行问题,可以考虑以下几点:

  1. 检查请求是否被多次发送:确保客户端没有发送两次相同的请求。
  2. 使用中间件处理请求:确保每次请求只处理一次。

下面是一个改进后的示例代码:

var MongoClient = require('./node_modules/mongodb').MongoClient;
var http = require('http');

var db = null;

MongoClient.connect('mongodb://127.0.0.1:27017/lbs', function(err, database) {
    if (err) throw err;
    db = database;

    var server = http.createServer(function(req, res) {
        db.collection('your_collection_name').findOne({ location: { $nearSphere: [118, 24], $maxDistance: 1 } }, function(err, result) {
            if (err) throw err;
            console.log("123" + result);
            res.end(JSON.stringify(result));
        });
    });

    server.listen(1234);
});

解释:

  1. MongoClient.connect: 确保数据库连接成功后,再创建 HTTP 服务器。
  2. HTTP 请求处理: 在 HTTP 请求处理函数中,直接查询数据库,而不是使用 eval 函数。
  3. 错误处理: 添加错误处理逻辑,以确保异常不会导致程序崩溃。

通过这种方式,你可以确保每次请求只处理一次 MongoDB 操作,并且避免重复执行问题。

回到顶部