asynchronous瀑布不正确保存与mongoose

这是我第一次使用asynchronous,虽然我已经search了networking,并尝试了系列和瀑布方法,我的结果是一样的。 我觉得我很接近这个工作正确,但不能得到它的工作100%。

我试图创build一个基于时间的testing,并testing从前端发送的问题参数。主要问题是最后一个创buildtesting的方法发生在search问题的中间方法之前,有任何,然后把它放在一个对象的数组。

一旦完成,testing正在创build,没有任何问题,但它确实节省了第一个function的时间。 最初(在尝试asynchronous之前)我在2秒的setTimeout中包装了“新的采访testing”方法,这工作得很好,但我知道有一个更好,更有效的方法来做到这一点。

exports.create = function(req) { console.log(req.body); var testTime = 0; var timer = req.body.timeValue; var testQuestions = req.body.category; var finalQuestions = []; async.waterfall([ function(callback) { **add total time into one value to be saved in the test** for (var i = 0; i < timer.length; i++) { if (timer[i] !== '') { testTime += parseInt(timer[i]); } } callback(null,testTime); }, function(testTime,callback) { **find question and push it into array of objects** for (var i = 0; i < testQuestions.length; i++) { allTestQuestions.findById(testQuestions[i], function(err, result) { var test = {}; test.text = result.text; test.answer = ''; test.sample = result.sample; finalQuestions.push(test); }); } callback(null, testTime, finalQuestions); }, function(testTime, finalQuestions, callback) { **create new test** new interviewTest({ authCode: req.body.intAuthCode, name: req.body.intName, questions: finalQuestions, **questions** assignedDate: new Date, started: false, startedTime: '1970', completed: false, completedTime: '1970', time: testTime, timePerQuestion: [] }).save(function(err, res) { console.log(err); if (!err) { console.log(res + " saved!"); } }); callback(null, 'done'); } ], function (err, result) { if (err) { callback(err); } console.log(result); }); } 

在中间函数中,您有一个for循环,它正在调用数据库,并且正在循环外调用callback函数。 它应该包装在另一个asynchronousfunction。 尝试async.each或按照Bergi的build议, async.map

 async.waterfall([ function(callback) { for (var i = 0; i < timer.length; i++) { if (timer[i] !== '') { testTime += parseInt(timer[i]); } } callback(null,testTime); }, function(testTime,callback) { async.each(testQuestions, function(tQuestion, eachCallback){ allTestQuestions.findById(tQuestion, function(err, result) { if(err){ // you can either eachCallback(err) or just console.log it and keep going } var test = {}; test.text = result.text; test.answer = ''; test.sample = result.sample; finalQuestions.push(test); eachCallback() }) }, function(err, result){ callback(null, testTime, finalQuestions); }) }, function(testTime, finalQuestions, callback) { new interviewTest({ authCode: req.body.intAuthCode, name: req.body.intName, questions: finalQuestions, assignedDate: new Date, started: false, startedTime: '1970', completed: false, completedTime: '1970', time: testTime, timePerQuestion: [] }).save(function(err, res) { console.log(err); if (!err) { console.log(res + " saved!"); } callback(null, 'done'); //call here }); // callback(null, 'done'); this should always be called inside the callback function } ], function (err, result) { if (err) { callback(err); } console.log(result); }); 

callback是外部asynchronousfunction(保存,和findById),像这样做:

 function(testTime,callback) { **find question and push it into array of objects** for (var i = 0; i < testQuestions.length; i++) { allTestQuestions.findById(testQuestions[i], function(err, result) { ... finalQuestions.push(test); if(finalQuestions.length == testQuestions.length) return callback(null, testTime, finalQuestions); }); } }, function(testTime, finalQuestions, callback) { **create new test** new interviewTest({ ... }).save(function(err, res) { console.log(err); if (!err) { console.log(res + " saved!"); } callback(null, 'done'); }); }