【问题标题】:Nodejs MongoDb Asynchronous CallbackNodejs MongoDb 异步回调
【发布时间】:2018-06-14 03:24:44
【问题描述】:

我刚刚开始使用 NodeJs 并处理异步函数。 我试图从一个 for 循环中执行多个 MongoDB 调用,我需要等待所有这些调用都完成,然后才能进行下一步。

我尝试使用异步来实现它,但似乎我在调用之外的所有变量都无法访问。知道如何使它工作吗?

    var sample = req.body;  // sample will be an array list of items
    var stringList = "";

    var calls = [];
    for(var i = 0; i < sample.length; i++) {
console.log(sample[].item) // i can print it here
        calls.push(function(callback) {
            db3.table.find({column1:sample[i].item}, function(err, temp){  // i hit an error here, it cannot find sample[i].item...
                if (err)
                    return callback(err);
                stringList = stringList + temp[0].item2;
                callback(null, stringList );
            });
        });
    }

    async.parallel(calls, function(err, result) {
        if (err)
            return console.log(err);

console.log(result); // I am expecting a string of all the item2 returned and concatenated previously

});

【问题讨论】:

  • 在循环中调用 DB (any) 不是一个好主意。大多数数据库都支持批量操作(插入、更新),您可以通过一个调用来完成。你能解释一下你对循环中的数据库有什么要求吗?
  • 这主要是因为我不确定如何使用 nodejs 和 MongoDB 进行复杂查询......我想要的是将其 column1 = 的几个项目的结果连接到我的几个值从请求体传入
  • 发布示例数据并详细说明您想要的任何内容

标签: node.js mongodb async.js


【解决方案1】:

异步并行回调无论如何都会将数据发送到最终回调,您可以使用此功能合并所有发送的值。

var sample     = req.body;  // sample will be an array list of items
var stringList = "";
var calls      = [];
for (var i = 0; i < sample.length; i++) {
    console.log(sample[i].item) // i can print it here
    calls.push(function (callback) {
        db3.table.find({column1: sample[i].item}, function (err, temp) {
            // i hit an error here, it cannot find sample[i].item...
            if (err) {
                return callback(err);
            }
            callback(null, temp[0].item2);
        });
    });
}

async.parallel(calls, function (err, result) {
    if (err) {
        return console.log(err);
    }
    stringList = result.join('');
    console.log(stringList); // I am expecting a string of all the item2 returned and concatenated previously
});

【讨论】:

  • 请恢复我的编辑,我编辑错了,无法恢复
【解决方案2】:

也许您可以检查所有数据库查询何时完成:

var sample = req.body;  // sample will be an array list of items
var stringList = "";
var counter = 0;
for(var i = 0; i < sample.length; i++) {
    console.log(sample[].item) // i can print it here
        db3.table.find({column1:sample[i].item}, function(err, temp){  // i hit an error here, it cannot find sample[i].item...
            if (err)
                throw err;
            stringList = stringList + temp[0].item2;
            if(++counter >= sample.length) {
                // when here you will have the whole string
                console.log(stringList); 
            }
        });
    });
}

【讨论】:

    【解决方案3】:

    每个异步操作都可以用回调或承诺来表达。这里有两个例子可能会有所帮助

    //  sequential execution P.S. use for dependent tasks  
    var operations= [1,2,3];
    (function loop(index){
        if(index==operations.length) return ;
        setTimeout(function() {
            console.log(`hello ${operations[index]}`);
            loop(++index);
        }, 1000);
    })(0)
    
    //  parallel execution P.S. use when independent tasks  
    Promise.all(operations.map(val=>{
        return new Promise((resolve, reject) => {
            console.log(`hello ${val}`);
        });
    }))
    .then(data=>{
    
    })
    .catch(err=>{
        console.log(err);
    })
    

    阅读更多https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

    【讨论】:

      猜你喜欢
      • 2017-05-15
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      相关资源
      最近更新 更多