使用异步node.js实现在Mongo集合中进行写入和读取

时间:2017-12-21 16:19:51

标签: node.js mongodb asynchronous callback closures

我是nodeJS的初学者,我在管理异步思维方式方面遇到了一些问题。

我尝试在MongoDB数据库中保存数据并检索它。我从websocket服务每1毫秒到5秒获取数据。

如果它每5秒没有问题,但每1毫秒,当我显示我的收藏内容时,数据尚未保存。

这是我的代码:

// --Websocket event coming every 1 ms--//
while (1) { //Simulate Websocket events coming every 1 ms
        dataBookSave(dataArrayfunction, function(log) { //array of data received from websocket event
                console.log(log); //Display the callback log from the function dataBookSave
                var query = ""; // Empty query in MongoDB to retrieve all data
                mongoDb.find(dbName, collectionName, query, function(result) { // get all data from the MongoDB collection.
                    console.log(results); //Display all data from my MongoDB collection
                });
            }
        }

        function dataBookSave(dataArray, callback) {
            if (dataArray.length < 1) callback("dataBookSave1"); //test if the array is empty. if yes, generate the callback
            for (var i = 0; i < dataArray.length; i++) {
                (function(i) { //closure the for loop
                    var objAdd = JSON.parse('{"data" : ' + dataArray[i] + ' }'); // create the object to add in the collection
                    mongoDb.insertCollection(dbName, collectionName, objAdd, function() { // insert function in MongoDB
                        if (i == dataArray.length - 1) // test if the loop is finished.
                        {
                            callback("dataBookSave2"); // if yes, generate the callback
                        }
                    });
                })(i);
            }
        }


function insertCollection(dbName, collectionName, myObj, callback) {
    var MongoClient = require('mongodb').MongoClient;
    var url = "mongodb://localhost:27017/" + dbName;

    MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        var dbase = db.db(dbName);

        dbase.collection(collectionName).insertOne(myObj, function(err, res) {
            if (err) throw err;
            db.close();
            callback();
        });
    });
}

function find(dbName, collectionName, query, callback) {
    var MongoClient = require('mongodb').MongoClient;
    var url = "mongodb://localhost:27017/" + dbName;
    MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        var dbase = db.db(dbName);

        dbase.collection(collectionName).find(query).sort({
            _id: -1
        }).toArray(function(err, result) {
            if (err) throw err;
            callback(result);
            db.close();
        });
    });
}

我看到执行for循环时,异步进程会迭代表的每个数据,并且不要等待执行insert数据库函数。当for循环完成后,我在MongoDB中读取集合。问题是数据仍然在队列中,将被写入集合中。

我该如何解决?放弃异步概念?使用封闭?找到最好的回调实现?

1 个答案:

答案 0 :(得分:0)

您绝对不希望每隔1ms连接/关闭与数据库的连接。在这种情况下建议保持连接打开。

我还没有运行下面的代码,但它应该可以运行

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

var mongodb;
var collectionName = "some-collection";

MongoClient.connect(url, function(err, db) {
    if (err) throw err;
    mongodb = db;

    run();
});

function run() {
      // --Websocket event coming every 1 ms--//
    while (1) { //Simulate Websocket events coming every 1 ms
        dataBookSave(dataArrayfunction, function(log) { //array of data received from websocket event

            console.log(log); //Display the callback log from the function dataBookSave

            find(collectionName, function(result) { // get all datas from the MongoDB collection.
                console.log(results); //Display all datas from my MongoDB collection
            });
        }); 
    }
}

function dataBookSave(dataArray, callback) {
    if (dataArray.length < 1) callback("dataBookSave1");

    var arr = [];
    // push object to arr for bulk insertion
    for (var i = 0; i < dataArray.length; i++) {
        arr.push({
            data: dataArray[i] 
        });
    }

    insert(collectionName, arr, function() {
        callback("dataBookSave2");
    });
}

function insert(col, arr, callback) {

    mongodb
    .collection(col)
    .insertMany(arr, function(err, res) {

        if (err) throw err;
        callback();
    });

}

function find(collectionName, query, callback) {

    mongodb
    .collection(collectionName)
    .find(query)
    .sort({ _id: -1 })
    .toArray(function(err, result) {

        if (err) throw err;
        callback(result);
    });
}