For循环在节点js中无法正常工作
For loop not working properly in node 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');
}
});
你做错了。 insert
是异步的,所以当 insert for i=1
完成并调用回调时,可能 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');
});
秒,使用 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);
}
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;
});
}
});
我是从头到尾写的。但是这里的基本思想是你需要一个无限循环到 运行,然后 resolve 一个 promise;分辨率触发继续循环,并增加计数器。
最好使用 async node.js library which provides control flows like running each function in series. You could use the 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');
}
);
});
您在 运行插入函数后调用了回调。它 运行 不完全在 运行 插入之后,而不是在循环中(它是异步的)。所以在你的代码中 res.redirrect 将永远不会被调用,因为在所有循环 运行 之后 finished 将为真。如果您不需要在回答之前完成所有这些插入,您可以这样做:
if(i == 29){
res.redirect('/client/client-list');
}
否则您需要创建一些队列,例如,我正在使用异步库 https://github.com/caolan/async 创建队列并 运行 在队列结束后回调。
使用承诺。我会做类似下面的事情
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');
}
});
我想通过 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');
}
});
你做错了。 insert
是异步的,所以当 insert for i=1
完成并调用回调时,可能 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');
});
秒,使用 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);
}
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;
});
}
});
我是从头到尾写的。但是这里的基本思想是你需要一个无限循环到 运行,然后 resolve 一个 promise;分辨率触发继续循环,并增加计数器。
最好使用 async node.js library which provides control flows like running each function in series. You could use the 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');
}
);
});
您在 运行插入函数后调用了回调。它 运行 不完全在 运行 插入之后,而不是在循环中(它是异步的)。所以在你的代码中 res.redirrect 将永远不会被调用,因为在所有循环 运行 之后 finished 将为真。如果您不需要在回答之前完成所有这些插入,您可以这样做:
if(i == 29){
res.redirect('/client/client-list');
}
否则您需要创建一些队列,例如,我正在使用异步库 https://github.com/caolan/async 创建队列并 运行 在队列结束后回调。
使用承诺。我会做类似下面的事情
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');
}
});