2017-08-29 79 views
0

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

我必须调用一个API并将offset作为参数传递给它。该API一次返回50条记录。所以,当我得到50条记录时,我将偏移量增加到51,并再次用偏移量51调用相同的API以获得下50条记录。这将继续,直到API给出少于50条记录。这是我可以退出的时候了。所以,我没有事先做好什么,可以定义循环将循环多久。这取决于以前的API响应。 在每个API调用中,我保存在我的数据库(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; 
} 

这个无限循环。 请帮忙!

+0

你必须使你的代码syncronous like,使用yield或async/await。 – Lazyexpert

+0

是的...我正在寻找如何使它同步。在这种情况下,你能帮助我一个例子吗? –

+0

它不会像你想象的那样同步.https://medium.com/@jamesmarino/the-best-feature-in-javascript-just-came-to-node-js-async-await-ebb7f5d60093 – Lazyexpert

回答

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

+0

谢谢!我会尝试这一个。我知道循环异步任务是错误的,但我对回调没有任何清晰的理解。这一个应该为我工作知道。 我每次都需要获取记录50,因为我从第三方API获取数据,并且在单次调用中有50条记录的限制,否则我会一次性提取所有记录。 –

+0

工作完美!谢谢 :) –