在nodejs中以循环同步方式运行MongoDB查询

时间:2017-08-29 12:16:52

标签: node.js mongodb

我是NodeJS和MongoDB的新手,我遇到了一个问题,我必须在循环中运行查询,查询的响应将决定是否必须继续循环。

我必须调用API并将offset作为参数传递给它。 API一次返回50条记录。因此,当我得到50条记录时,我将偏移量增加到51并再次使用偏移量51调用相同的API以获得接下来的50条记录。这将持续到API提供少于50条记录。这是我可以退出的时候。所以,我没有提前做任何事情来定义循环迭代的时间。这取决于以前的API响应。  在每个API调用中,我保存在我的db(MongoDB)中获取的数据。

这是我粗略的代码 -

var Client = require('node-rest-client').Client;
var client = new Client();
var MongoClient = require('mongodb').MongoClient;
var dburl = "mongodb://localhost:27017/mydb";
var repeat  =   true;
var result;
while(repeat){
    client.get('http://example.com?$offset='+offset, function (data, response) {
         result         =   JSON.parse(data);           
         num_records    =   ret.length;
         MongoClient.connect(dburl, function(err, db) {
             if (err) throw err;
             var collection = db.collection('myCollection');      
             collection.insertMany(result, function(err, res) {
                if (err) throw err;
                if(num_records < 50){
                     repeat =   false;
                }
                db.close();
             });      
          });
      });
      if(offset==0)
        offset  = 51;
      else
        offset  += 50;
}

这无限循环。 请帮忙!

1 个答案:

答案 0 :(得分:0)

你能在评论中告诉我为什么你需要50到50的记录?

首先:你要混合同步和异步代码:

var i = 0;
while (true) {
  client.get(url + offset, function(data, response) {
    /* deal with your response */
    console.log("hey, I'm asynchronous !");
  }
  console.log("i : " + i++);
}

在这里你将有这种输出:

// i : 1
// i : 2
// i : 3
// hey, I'm asynchronous !
// i : 4

回调函数中的代码不会停止循环。 如果您需要了解原因,以及它在JS中的工作原理,read this

所以,你不能在你的循环中放入异步代码,它会彻底结束。
但循环的另一种方式是递归,所以这是你可以做的:

function get50records(url, offset, callback) {
  DoYourrequests(_exemple, _exemple, function(requestResult) {
    if (youNeedToContinue) {
      console.log("offset : " + offset);
      get50records(url, offset + 50, callback);
    } else
      callback("end Message !");
  })
}

get50records(yourUrl, 50, function(res) {
  console.log(res);
  // continue to code here
})

因此,每次获得请求的结果时,如果需要继续,该函数将使用新的偏移调用自身,如果您不需要继续,它将调用回调你在第三个参数中传递的函数。

以下是日志的样子:

// offset : 50
// offset : 100
// offset : 150
// offset : 200
// end Message !

掌握callback pattern后,您可以了解Promise对象的工作原理,然后使用像async / await

这样的变体