Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js异步编码困难_Javascript_Node.js_Mongodb_Asynchronous - Fatal编程技术网

Javascript Node.js异步编码困难

Javascript Node.js异步编码困难,javascript,node.js,mongodb,asynchronous,Javascript,Node.js,Mongodb,Asynchronous,我试图从MongoDB获取多个文档,并将所有数据发送到一个数组中,但我在理解如何使用event-driven Node.js实现这一点时遇到了严重的问题 问题是在执行dataArray.push(tempObject)时,tempObject[“data”]=tempDataArray仍然没有执行 我的代码如下所示: app.post('/api/charts', function(req, res) { var names = req.body.names; var categorie

我试图从MongoDB获取多个文档,并将所有数据发送到一个数组中,但我在理解如何使用event-driven Node.js实现这一点时遇到了严重的问题

问题是在执行
dataArray.push(tempObject)
时,
tempObject[“data”]=tempDataArray
仍然没有执行

我的代码如下所示:

app.post('/api/charts', function(req, res) {
  var names = req.body.names;
  var categories = req.body.categories;

  var dataArray = [];

  for (i = 0; i < names.length; i++) {
    var tempObject = {};
    tempObject["name"] = names[i];
    Company.find({ name : names[i] }, function(err, result) {
      if (err) {
        throw err;
      }

      var tempDataArray = [];

      for (k = 0; k < categories.length; k++) {
        var tempDataObject = {};
        tempDataObject["name"] = categories[k];
        tempDataObject["numbers"] = result[0]["data"][categories[k]]["numbers"];
        tempDataObject["dates"] = result[0]["data"][categories[k]]["dates"];

        tempDataArray.push(tempDataObject);

      }
      tempObject["data"] = tempDataArray;
    });

    dataArray.push(tempObject);
  }

  res.send(dataArray);
});
var async = require("async");
app.post('/api/charts', function(req, res) {
    var names = req.body.names;
    var categories = req.body.categories;

    var dataArray = [];

    async.forEach(names, function(name, callback){

        var tempObject = {};
        tempObject["name"] = name;
        Company.find({ name : name }, function(err, result) {
            if (err) {
                callback(err);
            } else {
                var tempDataArray = [];

                for (k = 0; k < categories.length; k++) {
                    var tempDataObject = {};
                    tempDataObject["name"] = categories[k];
                    tempDataObject["numbers"] = result[0]["data"][categories[k]]["numbers"];
                    tempDataObject["dates"] = result[0]["data"][categories[k]]["dates"];

                    tempDataArray.push(tempDataObject);

                }
                tempObject["data"] = tempDataArray;
                dataArray.push(tempObject);
                callback();
            }
        });
    }, function(err){
        if(err){
            res.send(err);
        } else {
            res.send(dataArray);
        }
    });

});
app.post('/api/charts',函数(req,res){
变量名称=req.body.names;
var categories=req.body.categories;
var dataArray=[];
对于(i=0;i
如果您对如何正确实现预期结果有任何建议,我们将不胜感激。

请使用此库

https://github.com/caolan/async
使用此代码,您的代码将如下所示:

app.post('/api/charts', function(req, res) {
  var names = req.body.names;
  var categories = req.body.categories;

  var dataArray = [];

  for (i = 0; i < names.length; i++) {
    var tempObject = {};
    tempObject["name"] = names[i];
    Company.find({ name : names[i] }, function(err, result) {
      if (err) {
        throw err;
      }

      var tempDataArray = [];

      for (k = 0; k < categories.length; k++) {
        var tempDataObject = {};
        tempDataObject["name"] = categories[k];
        tempDataObject["numbers"] = result[0]["data"][categories[k]]["numbers"];
        tempDataObject["dates"] = result[0]["data"][categories[k]]["dates"];

        tempDataArray.push(tempDataObject);

      }
      tempObject["data"] = tempDataArray;
    });

    dataArray.push(tempObject);
  }

  res.send(dataArray);
});
var async = require("async");
app.post('/api/charts', function(req, res) {
    var names = req.body.names;
    var categories = req.body.categories;

    var dataArray = [];

    async.forEach(names, function(name, callback){

        var tempObject = {};
        tempObject["name"] = name;
        Company.find({ name : name }, function(err, result) {
            if (err) {
                callback(err);
            } else {
                var tempDataArray = [];

                for (k = 0; k < categories.length; k++) {
                    var tempDataObject = {};
                    tempDataObject["name"] = categories[k];
                    tempDataObject["numbers"] = result[0]["data"][categories[k]]["numbers"];
                    tempDataObject["dates"] = result[0]["data"][categories[k]]["dates"];

                    tempDataArray.push(tempDataObject);

                }
                tempObject["data"] = tempDataArray;
                dataArray.push(tempObject);
                callback();
            }
        });
    }, function(err){
        if(err){
            res.send(err);
        } else {
            res.send(dataArray);
        }
    });

});
var async=require(“async”);
app.post('/api/charts',函数(req,res){
变量名称=req.body.names;
var categories=req.body.categories;
var dataArray=[];
forEach(名称、函数(名称、回调){
var tempObject={};
tempObject[“name”]=名称;
Company.find({name:name},函数(err,result){
如果(错误){
回调(err);
}否则{
var tempDataArray=[];
对于(k=0;kCompany.find()方法将回调函数作为第二个参数。从数据库检索公司数据后,将调用此回调。这意味着在调用
Company.find()
方法后调用它之前,它可能在几毫秒到几百毫秒之间的任何位置。但是直接在
Company.find()之后的代码不会被延迟;马上就叫。因此,回调延迟就是为什么总是在
tempObject[“data”]=tempDataArray
之前调用
dataArray.push(tempObject)

在此基础上,外部for循环将同步运行,并且在每次迭代中,将进行单独的DB调用。这并不理想,因此我们希望将这个for循环放入回调中。所以我们可以做一些类似的事情:

app.post('/api/charts', function(req, res) {
    var names = req.body.names;
    var categories = req.body.categories;

    // we just do one DB query where all the data we need is returned
    Company.find({ name : names }, function(err, result) {
        if (err) {
            throw err;
        }

        var dataArray = [];

        // we iteratre through each result in the callback, not outside it since
        // that would cause blocking due to synchronous operation
        for (i = 0; i < result.length; i++) {
            var tempObject = {};
            tempObject["name"] = result[i].name;

            var tempDataArray = [];

            for (k = 0; k < categories.length; k++) {
                var tempDataObject = {};
                tempDataObject["name"] = categories[k];
                tempDataObject["numbers"] = result[i]["data"][categories[k]]["numbers"];
                tempDataObject["dates"] = result[i]["data"][categories[k]]["dates"];

                tempDataArray.push(tempDataObject);     
            }

            tempObject["data"] = tempDataArray;
            dataArray.push(tempObject);
        }
        res.send(dataArray);
    });
});
app.post('/api/charts',函数(req,res){
变量名称=req.body.names;
var categories=req.body.categories;
//我们只需执行一个DB查询,返回所有需要的数据
Company.find({name:names},函数(err,result){
如果(错误){
犯错误;
}
var dataArray=[];
//我们在回调中迭代每个结果,而不是在回调之外
//这将由于同步操作而导致阻塞
对于(i=0;i
对于抽象节点的事件驱动性质,有许多方法,如承诺(可以在ECMA脚本6或承诺库(如Bluebird、Async等)中访问)。但以上是一种基本的回调方法,通常用于Express之类的应用程序。

只需更改以下内容:

tempObject["data"] = tempDataArray;
});
dataArray.push(tempObject);
致:


你能在Nodejs中使用Promise对象吗?我在理解它的工作原理时遇到了类似的困难。看一看。简言之,当您有数据时,您需要对所有内容进行后期处理,即在find的回调中,打包并发送响应,正如@kyrylkov所说的。是的。在这个forEach示例中,所有名称都将并行执行,一旦全部执行完毕,您将得到最后一个回调函数(err),在该函数中,我们使用res.send进行响应。如果您不希望并行执行,或者希望基于名称数组维护结果顺序,那么可以使用ForEachLimit,这将解决问题
res.send(dataArray)
将在执行大部分(如果不是全部的话)回调之前被调用。而且它没有解决正在使用的同步方法。