Javascript Node.js | MongoDB count():在插入数据之前和之后获取计数

Javascript Node.js | MongoDB count():在插入数据之前和之后获取计数,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,我试图获取数据库中的项目数,以确认数据插入是否成功 在插入之前获取计数 插入 插入后获取计数 Console.log摘要 注:我知道这可以通过使用一些简单的函数来实现: dbName.equal(insertSize, result.insertedCount) 然而,我是javascript新手,我认为我遇到了实现异步回调的需要,所以我想弄清楚这一点 插入功能 var insertMany = function() { // get initial count var co

我试图获取数据库中的项目数,以确认数据插入是否成功

  • 在插入之前获取计数
  • 插入
  • 插入后获取计数
  • Console.log摘要
  • 注:我知道这可以通过使用一些简单的函数来实现:

    dbName.equal(insertSize, result.insertedCount)
    
    然而,我是javascript新手,我认为我遇到了实现异步回调的需要,所以我想弄清楚这一点

    插入功能

    var insertMany = function() {
    
        // get initial count
        var count1 = getDbCount();
    
        // Insert new 'data'
        MongoClient.connect(url, function(err, db) {
            var col = db.collection(collectionName);
            col.insert(data, {w:1}, function(err,result) {});
            db.close();
        });
    
        /** This needs to be implemented through next/callback
            after the insert operation  **/
        var count2 = getDbCount(); 
    
        /** These final console logs should be executed after all
            other operations are completed **/    
        console.log('[Count] Start: ' + count1 + ' | End:' +count2);
        console.log('[Insert] Expected: ' + data.length + ' | Actual: ' + (count2 - count1));
    
    };
    
    var getDbCount = function() {
        MongoClient.connect(url, function(err, db) {
            if (err) console.log(err);
    
            var col = db.collection(collectionName);
    
            col.count({}, function(err, count) {
                if (err) console.log(err);
                db.close();
                console.log('docs count: ' + count);
                // This log works fine
            });
    
        });
    
        return count; // this is returning as undefined since this is
                      // executing before the count operation is completed
    };
    
    获取数据库计数功能

    var insertMany = function() {
    
        // get initial count
        var count1 = getDbCount();
    
        // Insert new 'data'
        MongoClient.connect(url, function(err, db) {
            var col = db.collection(collectionName);
            col.insert(data, {w:1}, function(err,result) {});
            db.close();
        });
    
        /** This needs to be implemented through next/callback
            after the insert operation  **/
        var count2 = getDbCount(); 
    
        /** These final console logs should be executed after all
            other operations are completed **/    
        console.log('[Count] Start: ' + count1 + ' | End:' +count2);
        console.log('[Insert] Expected: ' + data.length + ' | Actual: ' + (count2 - count1));
    
    };
    
    var getDbCount = function() {
        MongoClient.connect(url, function(err, db) {
            if (err) console.log(err);
    
            var col = db.collection(collectionName);
    
            col.count({}, function(err, count) {
                if (err) console.log(err);
                db.close();
                console.log('docs count: ' + count);
                // This log works fine
            });
    
        });
    
        return count; // this is returning as undefined since this is
                      // executing before the count operation is completed
    };
    
    我收到错误,因为返回发生在所需操作完成之前

    谢谢你的帮助


    [EDIT]带承诺的getCount函数

    首先,我向getCount函数添加了承诺:

    var getCount = function() {
    
        var dbCount = 0;
    
        var promise = new Promise(function(resolve, reject) {
    
            MongoClient.connect(url, function(err, db) {
    
                if (err) {
                    console.log('Unable to connect to server', err);
                } else {
                    console.log('Database connection established:' + dbName);
                }
    
                // Get the collection
                var col = db.collection(collectionName);
    
                col.count({}, function(err, count) {
                    if (err) console.log(err);
                    db.close();
                    console.log('docs count: ' + count);
                    resolve(null);
                    dbCount = count;
                });
    
            });
    
        });
    
        promise.then(function() {
            return dbCount;
        });
    
    };
    
    console.log(getCount());
    
    输出仍然是: 未定义 已建立数据库连接:testdb 文件数:500


    然后({return count})代码仍在承诺{db.count()}之前执行。它在数据库操作完成之前返回未定义。

    返回在操作完成之前发生的原因是继承自javascript的nodejs的
    异步设计。当程序向前移动并遇到
    返回时,来自
    Mongoose.connect()
    的回调被留下来执行操作

    您没有提供使您进入错误语句的解决方案,因此我无法评论您在那里所做的错误。但是,考虑到您第一次完成所开始的工作,确保
    Mongoose.connect()
    完成并执行return语句的最佳方法是使用JavaScript。使用Promissions将使您的
    Mongoose.connect()
    执行,然后将控件传递给return语句

    您的代码将类似于:

    插入函数

    var insertMany = function() {
    
    // get initial count
    var count1 = getDbCount();
    
    // Insert new 'data'
    var promise = new Promise(
        function(resolve,reject){
          MongoClient.connect(url, function(err, db) {
            var col = db.collection(collectionName);
            col.insert(data, {w:1}, function(err,result) {});
            db.close();
            resolve(null);
          });
        }
      );
      promise.then(function(val){    
        var count2 = getDbCount();
    
        /** These final console logs should be executed after all
        other operations are completed **/
        console.log('[Count] Start: ' + count1 + ' | End:' +count2);
        console.log('[Insert] Expected: ' + data.length + ' | Actual: ' + (count2 - count1));
    });
    
    类似地,您可以向
    GetDB
    函数添加承诺。 执行承诺时的关键点包括:

  • then()
    包含在执行承诺后要同步执行的函数部分。它由
    resolve
    调用,传递的参数在
    catch
    函数的回调中接收
  • catch()
    包含在承诺中遇到错误时调用的函数部分。它由
    reject
    调用,传递的参数在
    catch
    函数的回调中接收

  • 编辑:promise的另一种选择是,与promises不同的是,它是一个外部模块。

    通常,您遇到的问题是,当函数返回时,您希望值已经存在。对于异步函数,通常情况并非如此。关于异步处理有大量信息(不要与Java中的并行处理混淆)

    我创建了一个适合您情况的示例:


    最后一件事。您可能希望签出“异步”包。这对解决这些问题有很大帮助,提供了很多帮助函数和控制流内容。

    如果你不展示你所做的,那么告诉你做错了什么有点难。错误应随附发生错误的行的一些信息。请提供发生错误的代码块以及调用该错误的部分,至少我已经把它去掉了。我在通过回调实现方面没有取得多大进展,这就是为什么我没有包括它。如果我取得进展,我将更新并添加新代码。Thanks@CarloP.LasMarias您永远不应该满足于
    setTimeout
    。有很多文章专门在后端解释函数的残暴性。Promise是为处理这种情况而开发的一个模块,如果它不起作用,那么问题就出在需要解决的代码中的某个地方。Async.js是另一个比
    setTimeout
    好得多的选项。请注意,此代码仍然会失败。在我编写代码之后,count2将具有值“undefined”@newBee,我已经提到,
    GetDB
    也必须以这种方式执行。然后,count将有一个值返回到count2。谢谢@RitikSaxena,我尝试了这个,但仍然得到相同的错误。即使在添加承诺之后,then语句仍在承诺之前执行。我在上面添加了修改后的getCount。@CarloP.LasMarias,您正在调用
    resolve
    ,然后为
    dbCount
    赋值。因此,您的
    dbCount
    永远不会被分配。尝试以下操作:将
    null
    替换为
    count
    内部解析。然后在
    函数的回调中,接收一个参数并将其分配给
    dbCount
    @RitikSaxena,我已尝试解析(count);dbCount=count;,而且顺序也颠倒了。仍然是相同的结果,dbCount=undefined。
    setTimeout
    是一种糟糕的做法。不建议特别在I/O任务中使用超时。通过随机延迟代码,您正在消耗一段时间。这会在开发复杂网站时消耗您的资源。@Ritik Saxena此处的超时只是对原始海报上的db调用的替换,使示例更易于阅读。在您提到的资源问题上,我们也无法关注您。将代码延迟到下一个事件循环中并不少见。当然,尽管您会始终使用“0”超时。@newBee使用setTimeout替换db调用以使示例更易于阅读,但我希望您不是说添加它是为了使示例更可读,而没有任何其他目的。是吗?此外,
    reject
    用于传递承诺中的错误,这些错误在catch语句中处理。因此,您可能需要编辑注释
    null=no error
    ,因为这里的null表示代码没有要传递给
    的内容<