Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.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
如何在for循环(Node.JS)中处理回调_Node.js_Mongodb_Mongoose - Fatal编程技术网

如何在for循环(Node.JS)中处理回调

如何在for循环(Node.JS)中处理回调,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我试图用NodeJS编写代码,从外部API获取数据,然后使用Mongoose在MongoDB中填充它们。在此期间,我将检查Mongo中是否已经存在该特定项。下面是我的代码 router.route('/report') // the REST api address .post(function(req, res) // calling a POST { console.log('calling report API'); var object = "report/"

我试图用NodeJS编写代码,从外部API获取数据,然后使用Mongoose在MongoDB中填充它们。在此期间,我将检查Mongo中是否已经存在该特定项。下面是我的代码

router.route('/report') // the REST api address
  .post(function(req, res) // calling a POST 
  {
    console.log('calling report API');
    var object = "report/" + reportID; // related to the API
    var parameters = '&limit=100' // related to the API
    var url = link + object + apiKey + parameters; // related to the API

    var data = "";
    https.get(url, function callback(response)
    {
      response.setEncoding("utf8");
      response.on("data", function(chunk)
      {
        data += chunk.toString() + ""; 
      });

      response.on("end", function()
      {
        var jsonData = JSON.parse(data);
        var array = jsonData['results']; // data is return in array of objects. accessing only a particular array
        var length = array.length;
        console.log(length);

        for (var i = 0; i < length; i++) 
        {
          var report = new Report(array.pop()); // Report is the schema model defined. 
          console.log('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^');
          console.log(i);
          console.log('*****************************');
          console.log(report);
          console.log('*****************************');
          // console.log(report['id']);

          /*report.save(function(err)
          {
            if(err)
              res.send(err);
          });*/

          Report.find({id:report['id']}).count(function(err, count) // checks if the id of that specific data already exists in Mongo
          {
            console.log(count);
            console.log('*****************************');
            if (count == 0) // if the count = 0, meaning not exist, then only save
            {
              report.save(function(err)
              {
                console.log('saved');
                if(err)
                  res.send(err);
              });
            }
          });
        };
        res.json({
                    message: 'Grabbed Report'
                  }); 
      });
      response.on("error", console.error);
    });
  })
router.route('/report')//RESTAPI地址
.post(函数(req,res)//调用post
{
log(“调用报告API”);
var object=“report/”+reportID;//与API相关
var参数='&limit=100'//与API相关
var url=link+object+apiKey+parameters;//与API相关
var数据=”;
https.get(url,函数回调(响应)
{
响应。设置编码(“utf8”);
关于(“数据”,函数(块)
{
数据+=chunk.toString()+“”;
});
on(“end”,function())
{
var jsonData=JSON.parse(数据);
var array=jsonData['results'];//返回对象数组中的数据。仅访问特定数组
var length=array.length;
控制台日志(长度);
对于(变量i=0;i
我的问题是,由于NodeJS回调是并行的,所以不会按顺序调用它。我的最终结果是这样的:

  • 调用报表API
  • 控制台日志(长度)=100
  • ^^^^^^^^^^^^^^^^^^^^^^^^
  • console.log(i)=以0开头
  • *******************************
  • console.log(report)=将存储在Mongo中的数据
  • *******************************
  • 当长度等于100时,数字3-7重复100次
  • console.log(count)=0或1
  • 数字9重复100次
  • console.log('saved')
  • 数字11重复100次
  • 最后,100个数据中只有最后一个存储到Mongo中
  • 我需要的是某种技术或方法来处理这些一个接一个执行的回调,而不是按照循环顺序执行。我很确定这就是问题所在,因为我的其他RESTAPI都在工作

    我已经研究过异步方法、承诺、递归函数和其他一些我真正理解如何解决这个问题的方法。我真的希望有人能对这件事有所了解


    如果我问问题的方式有任何错误,请随时纠正我。这是我在StackOverflow中发布的第一个问题。

    您可以使用库来控制执行流。还有用于处理数组的迭代器。

    您可以使用库来控制执行流。还有用于处理数组的迭代器。

    这个问题被称为。 还有很多其他方法,比如使用和库

    我对当地人将带来的, 您可以从今天开始使用transpiler库

    但到目前为止,我发现最简单的方法是: 取出长回调函数并在外部定义它们

    router.route('/report') // the REST api address
        .post(calling_a_POST)
    
    function calling_a_POST(req, res) {
        ...
        var data = "";
        https.get(url, function callback(response) {
            ...
            response.on("end", response_on_end_callback); // --> take out
            response.on("error", console.error);
        });
    }
    
    function response_on_end_callback() {                 // <-- define here
        ...
        for (var i = 0; i < length; i++) {
            var report = new Report(array.pop());
            ...
            Report.find({ id: report['id'] })
                  .count(Report_find_count_callback);     // --> take out
        };
        res.json({
            message: 'Grabbed Report'
        });
    }
    
    function Report_find_count_callback(err, count) {     // <-- define here
        ...
        if (count == 0) {
            report.save(function(err) {                   // !! report is undefined here
                console.log('saved');
                if (err)
                    res.send(err);                        // !! res is undefined here
            });
        }
    }
    
    另一个我可以预见的问题,实际上可能不会出现在这里,但无论如何还是最好讨论一下。
    data
    变量,因为它是一个字符串,与对象不同,它是一种基本类型,所以它是“按值传递的”。

    最好将变量包装在对象中并传递对象,因为javascript中的对象总是“通过引用传递”

    调用POST的函数(req、res){ ... //var data=“”;// var data_wrapper={}; data_wrapper.data={};//将其包装在对象中 https.get(url,函数回调(响应){ ... 关于(“数据”,函数(块){ data_wrapper.data+=chunk.toString()+“”//使用点表示法引用 }); 在“结束”时,函数(err){ 响应_on_end(err,data _wrapper,res);//并传递该对象 }); 响应.on(“错误”,控制台.error); }); } 函数响应\u在\u结束\u回调上(err、数据\u包装器、res){ var data=data\u wrapper.data;//稍后重新定义变量 ... 对于(变量i=0;i
    此问题被称为。 还有很多其他方法,比如使用和库

    我对当地人将带来的, 您可以从今天开始使用transpiler库

    但到目前为止,我发现最简单的方法是: 取出长回调函数并在外部定义它们

    router.route('/report') // the REST api address
        .post(calling_a_POST)
    
    function calling_a_POST(req, res) {
        ...
        var data = "";
        https.get(url, function callback(response) {
            ...
            response.on("end", response_on_end_callback); // --> take out
            response.on("error", console.error);
        });
    }
    
    function response_on_end_callback() {                 // <-- define here
        ...
        for (var i = 0; i < length; i++) {
            var report = new Report(array.pop());
            ...
            Report.find({ id: report['id'] })
                  .count(Report_find_count_callback);     // --> take out
        };
        res.json({
            message: 'Grabbed Report'
        });
    }
    
    function Report_find_count_callback(err, count) {     // <-- define here
        ...
        if (count == 0) {
            report.save(function(err) {                   // !! report is undefined here
                console.log('saved');
                if (err)
                    res.send(err);                        // !! res is undefined here
            });
        }
    }
    
    另一个我可以预见的问题,实际上可能不会出现在这里,但无论如何还是最好讨论一下。
    数据<
    
    function calling_a_POST(req, res) {
        ...
        var data = "";
        https.get(url, function callback(response) {
            ...
            //sponse.on("end", function(err, data){
            response.on("end", function(err){ // data shouldn't be here
                response_on_end(err, data, res);
            });
            response.on("error", console.error);
        });
    }
    
    function calling_a_POST(req, res) {
        ...
        // var data = ""; // 
        var data_wrapper = {};
        data_wrapper.data = {};                                // wrap it in an object
        https.get(url, function callback(response) {
            ...
            response.on("data", function(chunk){
                data_wrapper.data += chunk.toString() + "";   // use the dot notation to reference
            });
            response.on("end", function(err){ 
                response_on_end(err, data_wrapper, res);      // and pass that object
            });
            response.on("error", console.error);
        });
    }
    
    function response_on_end_callback(err, data_wrapper, res) {
        var data = data_wrapper.data;                         // later redefine the variable
        ...
        for (var i = 0; i < length; i++) {
            var report = new Report(array.pop());
            ...