node-mongoskin如何批量添加?

2013-01-29 15:45:42 +08:00
 skynothing
因node-mongoskin是异步操作的,当我如下执行批量杯具就出现了:
for(var i=0;i<results.length;i++){
var result=results[i];
var name=result['name']
db.user.findOne({'name':name},function (err,user_result) {
if(user_result==null){
db.user.insert({'name':name});
}
});


运行结果是:如果有10条记录就会在数据库添加了10条最后一个name相同的记录。
4649 次点击
所在节点    Node.js
12 条回复
ljbha007
2013-01-29 16:23:07 +08:00
这个不是node-mongoskin的问题 这是javascript闭包的问题 var name 最终的值是results最后一个name所以所有的回调函数能访问到的name变量都变成了 results里边最后一个name

比如
var arr = ['a', 'b', 'c', 'd']
for (var i = 0; i< arr.length;i++){
var r = arr[i];
setTimeout(function(){console.log(r)}, 500);
}
最后结果是4个d

你把db.user.insert({'name':name});换成db.user.insert({'name':user_result['name']});就好了
虽然不是干净 但是能解决问题
skynothing
2013-01-29 16:39:12 +08:00
@ljbha007 你的意思我明白了。不过你的回答还是没解决问题。
ljbha007
2013-01-29 16:56:19 +08:00
@skynothing

for(var i=0;i<results.length;i++){
var result=results[i];
var name=result['name']
function makeCallback(val){
return function (err,user_result) {
if(user_result==null){
db.user.insert({'name':val});
}
}
}
db.user.findOne({'name':name},makeCallback(name));
skynothing
2013-01-29 17:06:13 +08:00
@ljbha007 太牛了。谢谢!
fanwei
2013-01-29 18:33:03 +08:00
不用for循环,用map之类的函数来遍历,代码改动较小,你也比较好理解
results.map(function(){
var name=result['name']
db.user.findOne({'name':name},function (err,user_result) {
if(user_result==null){
db.user.insert({'name':name});
}
});
});
fanwei
2013-01-29 18:34:29 +08:00
少写了个result

results.map(function(result){
var name=result['name']
db.user.findOne({'name':name},function (err,user_result) {
if(user_result==null){
db.user.insert({'name':name});
}
});
});
ljbha007
2013-01-29 19:25:26 +08:00
@fanwei 原来是这样 学习了
skynothing
2013-01-30 16:19:00 +08:00
@fanwei 高手呀。。学习
jinwyp
2013-02-05 13:42:49 +08:00
// Bulk update
app.put('/api/products', function (req, res) {
var i, len = 0;
console.log("is Array req.body.products");
console.log(Array.isArray(req.body.products));
console.log("PUT: (products)");
console.log(req.body.products);
if (Array.isArray(req.body.products)) {
len = req.body.products.length;
}
for (i = 0; i < len; i++) {
console.log("UPDATE product by id:");
for (var id in req.body.products[i]) {
console.log(id);
}
ProductModel.update({ "_id": id }, req.body.products[i][id], function (err, numAffected) {
if (err) {
console.log("Error on update");
console.log(err);
} else {
console.log("updated num: " + numAffected);
}
});
}
return res.send(req.body.products);
});
heroicYang
2013-02-06 12:35:17 +08:00
mongoskin支持批量插入的...为嘛要each、要map? https://github.com/kissjs/node-mongoskin#insertdocs-options-callback
skynothing
2013-02-06 18:12:44 +08:00
@heroicYang 请问有例子吗?没看懂。
heroicYang
2013-02-07 16:05:57 +08:00
@skynothing 第一个参数是你要插入的文档对象(或数组),第二个参数是一些可选项,如果想在第三参数即回调函数 callback 中取到插入的文档,可选项中请传入 { safe: true }。这样 callback 会传入两个参数:err 和 records,records即为插入之后的文档对象数组。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/59169

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX