For循环在节点js中不能正常工作

我想通过for循环插入多个数据,但是这个代码只添加2或3个数据,然后继续加载,但没有发生任何事情…

router.post('/addclient' , function (req , res){ var finished = false; var user = req.body.username; for(var i = 0 ; i <30 ; i++){ req.body.username = user + i ; objDB.insert("clientList" ,req.body, function(err, data){ //if(err) console.log(err); if(i>20){ finished = true; } }); } if(finished){ res.redirect('/client/client-list'); } }); 

如果你使用async node.js库来提供控制stream,比如像串行运行每个函数,那将是最好的。 您可以使用async.whilst()方法并重构您的代码:

 router.post('/addclient', function(req, res) { var user = req.body.username, count = 0, result = { finished = false }; async.whilst( function () { return count < 30; }, function (callback) { count++; req.body.username = user + count.toString(); objDB.insert("clientList", req.body, function(err, data){ if (err) { return callback(err); } result["data"] = data; if( count > 20 ) result.finished = true; callback(null, result); }); }, function (err, result) { if (err) { /* handle err */}; if (result.finished) res.redirect('/client/client-list'); } ); }); 

你做错了。 insert是asynchronous的,所以当插入i=1完成,callback被调用,也许i等于20多,你不能猜到它。 你缺less同步和asynchronous的概念和差异。

这里有两个解决你的问题的方法:

首先,一次添加30个项目:

 var clientsList = []; for (var i = 0 ; i < 30 ; i++) { clientsList[i] = Ith client object; // create object you want to insert for client i } // for example insertAtOnce is a function to insert your list objDB.insertAtOnce(clientsList,function(err,callback) { if (err) console.log("error : ", err); res.redirect('/client/client-list'); }); 

第二,使用bind

 function insertCallback(itr, res, err,callback) { if (itr == 29) { res.redirect('/client/client-list'); } } ---- for(var i = 0 ; i <30 ; i++){ req.body.username = user + i ; objDB.insert("clientList" ,req.body,insertCallback.bind(null, i, res); } 

在运行插入function之后调用一个callback函数。 它运行不完全后运行插入,而不是循环(它是asynchronous)。 所以在你的代码中,res.redirrect将永远不会被调用,因为在所有的循环运行之后,结束将是真的。 如果你不需要在回答之前完成所有的插入操作,你可以这样做:

 if(i == 29){ res.redirect('/client/client-list'); } 

否则,你需要创build一些队列,例如,我使用asynchronous库https://github.com/caolan/async创build队列,并在队列结束后运行callback&#x3002;

 router.post('/addclient', function(req, res) { var finished = false; var user = req.body.username; var i = 0; while( true ) { if ( i > 20 ) { res.redirect('/client/client-list'); } req.body.username = user + i; var promise = new Promise(); objDB.insert("clientList", req.body, function(err, data) { promise.resolve(); }); promise.then(function() { i++; continue; }); } }); 

我从头顶上写下了它。 但是这里的基本思想是你需要一个无限循环,然后解决一个承诺; 该决议触发继续循环,并增加计数器。

使用承诺。 我会做下面的事情

  router.post('/addclient' , function (req , res){ var finished = false; var promise = []; var user = req.body.username; for(var i = 0 ; i <30 ; i++) { req.body.username = user + i; promise.push(new Promise(resolve, reject) { objDB.insert("clientList" ,req.body, function(err, data) { if(err) { reject(err) return } resolve(data) }) }) } Promise.all(promise).then(function() { finished = true }) if(finished){ res.redirect('/client/client-list'); } });