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

Node.js For循环在节点js中工作不正常,node.js,mongodb,express,monk,Node.js,Mongodb,Express,Monk,我想通过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.ins

我想通过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');      
    }
});
router.post('/addclient',函数(req,res){
var finished=false;
var user=req.body.username;
对于(变量i=0;i 20){
完成=正确;
}
});
}
如果(完成){
res.redirect('/client/client list');
}
});

你做错了
insert
是异步的,所以当insert for
i=1
完成并调用callback时,可能
i
等于20或更多,您猜不到它。您缺少同步和异步的概念和差异

以下是解决您问题的两个解决方案:

首先,一次添加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');    
});

我是从头开始写的。但这里的基本思想是,你需要一个无限运行的循环,然后解决一个承诺;分辨率触发继续循环,并递增计数器

最好使用node.js库,该库提供控制流,如串联运行每个函数。您可以使用方法将代码重新构造为:

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');
        }
    );
});
router.post('/addclient',函数(req,res){
var user=req.body.username,
计数=0,
结果={finished=false};
异步的(
函数(){返回计数<30;},
函数(回调){
计数++;
req.body.username=user+count.toString();
objDB.insert(“客户端列表”、请求主体、函数(错误、数据){
if(err){返回回调(err);}
结果[“数据”]=数据;
如果(计数>20)result.finished=true;
回调(null,result);
});     
},
函数(错误、结果){
if(err){/*句柄err*/};
if(result.finished)res.redirect('/client/client list');
}
);
});

您在运行insert函数后调用了一个回调函数。它不完全在运行insert之后运行,也不在循环中运行(它是异步的)。所以在代码中永远不会调用res.redirect,因为在所有循环运行之后finished将为true。如果您不需要在回答之前完成所有这些插入,您可以这样做:

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

否则您需要创建一些队列,例如,我正在使用异步库创建队列,并在队列结束后运行回调。

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

 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');      
    }
});
router.post('/addclient',函数(req,res){
var finished=false;
var promise=[];
var user=req.body.username;

对于(var i=0;我想你比我先做一步。)那么我们能做什么?你到底想做什么?你想插入30个新客户端,但在插入20个客户端后重定向用户?为什么不一次插入客户端?我只想添加30个客户端,添加表单太长,所以我无法添加30次仅添加1个文档
if(i == 29){
         res.redirect('/client/client-list');      
}
 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');      
    }
});