【问题标题】:Write and read in Mongo collection with asynchronous node.js implementation使用异步 node.js 实现在 Mongo 集合中读写
【发布时间】:2018-06-04 08:41:05
【问题描述】:

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

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

每5秒没有问题,但每1ms,当我显示我的收藏内容时,数据还没有保存。

这是我的代码:

// --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循环执行时,异步过程迭代表的每个数据,不等待插入数据库函数执行。当 for 循环完成后,我读取了 MongoDB 中的集合。问题是数据仍在队列中,将被写入集合中。

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

【问题讨论】:

    标签: node.js mongodb asynchronous callback closures


    【解决方案1】:

    您绝对不想每 1 毫秒连接/关闭与您的数据库的连接。在这种情况下,建议保持连接打开。

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

    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);
        });
    }
    

    【讨论】:

    • 谢谢。我今天会试试。只是一个问题,你为什么要创建另一个数组 "arr" ?是不是不能直接用“dataArray”和“insert”函数?
    • 我不知道dataArray是什么样的,你用var objAdd = JSON.parse('{"data" : ' + dataArray[i] + ' }');这就是为什么我用arr.push({data: dataArray[i]});如果dataArray是一个对象数组那么你可以直接使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多