NodeJS:callback和asynchronous调用

我一直在盯着我的屏幕太久,似乎无法弄清楚这一点…基本上我做3查询使用mongoose,每一个build设在另一个的结果。 由于某种原因,家长电话会在孩子完成任务之前完成。 这是我的代码,为什么父母不等待继续直到孩子完成了工作? 我怎样才能让代码运行,因为我想要它:-)

我被告知使用承诺,但它看起来如此复杂的使用,我认为使用callback将足以处理asynchronous调用或我错了吗?

var ctr = 0; // counter 1 var ct2 = 0; // counter 2 //Array to be used for the header of the csv file var mainArr = [["Personeelsnummer", "Chauffeur", "Week 1", "Week 2", "Week 3", "Week 4"]]; // Find all users in the database User.find({}).exec(function (err, users){ // forEach user, push some basic data into tempArr // and lookup planned weeks (geplandeWeken) using another mongoose function users.forEach(function(user){ var tempArr = []; tempArr.push(user.personeelsnummer); tempArr.push(user.fullName); user.geplandeWeken.forEach(function(week1){ Week.findById(week1, function(err, foundWeek){ tempArr.push(foundWeek.week); ctr++; if(ctr === user.geplandeWeken.length){ mainArr.push(tempArr); console.log(mainArr); } }); }); ct2++; }); if(ct2 === users.length){ console.log(ct2); csv.write(mainArr, {headers:true}).pipe(res); } }); 

所以长话短说: users.forEachuser.geplandeWeken.forEach之前完成是能够做它的工作。 在收集任何数据并存储到csv文件之前,将csv文件发送给用户。

首先,您已经同步编写了代码,这就是为什么它不会等待您的依赖关系解决并继续之后。

为此,你会想要使用callback或承诺。 如果写回合可能导致callback地狱,我更喜欢后者作为一些复杂的代码。

有关承诺的参考: 承诺

因此,根据您的要求,您可以使用如下的承诺:通过npm安装蓝鸟(我更喜欢它,也可以使用任何其他软件包),并在主文件中使用它

 var Promise = require("bluebird"); mongoose.Promise = Promise; 

使用承诺来制作自定义函数,您可以使用以下内容

 function sample(required Params){ return new Promise(function(resolve,reject){ //do things you want to perform resolve(params you want to sendBack)//if everything has worked correctly reject(params you want to sendBack)// if something goes wrong }; } 

根据你的代码,我已经用承诺修改了它,我能理解的最好

 var ctr = 0; var ct2 = 0; var mainArr = [["Personeelsnummer", "Chauffeur", "Week 1", "Week 2", "Week 3", "Week 4"]]; User.find({}) .then(function(users){ for(user in users){ var tempArr = []; tempArr.push(user.personeelsnummer); tempArr.push(user.fullName); for(week1 in user.geplandeWeken){ Week.findById(week1) .then(function(foundWeek){ tempArr.push(foundWeek.week); ctr++ if(ctr === user.geplandeWeken.length){ mainArr.push(tempArr); console.log(mainArr); } }); } if(ct2 === users.length){ console.log(ct2); csv.write(mainArr, {headers:true}).pipe(res); } } }) .catch(function(err){ //this is the common error handler //code for handling error }); 

因为你使用的是基于json的语言,也就是javascript,所以试着用你的tempArr作为json,因为如果你需要给你的tempArrvariables添加一些新的值或者你决定洗牌的话,它会给你更多的灵活性和更less的变化存储在variables中的值

 var tempArr = {}; tempArr[keyName]=keyValue; 

并访问它像这样tempArr.keyName;

希望这回答您的查询

Week.findById是asynchronous的。 它不会阻止代码执行,并继续下一个指令。

如果在继续之前需要等待很多asynchronous任务完成,那么可以使用Promise 。

 var userPromises = users.map(user => { return new Promise((resolve, reject) => { // do something async // resolve(value) when complete }) }) Promise.all(userPromises).then(results => { // do something with results })