node-mongoskin如何批量添加?

2013 年 1 月 29 日
 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相同的记录。
5425 次点击
所在节点    Node.js
12 条回复
ljbha007
2013 年 1 月 29 日
这个不是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 年 1 月 29 日
@ljbha007 你的意思我明白了。不过你的回答还是没解决问题。
ljbha007
2013 年 1 月 29 日
@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 年 1 月 29 日
@ljbha007 太牛了。谢谢!
fanwei
2013 年 1 月 29 日
不用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 年 1 月 29 日
少写了个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 年 1 月 29 日
@fanwei 原来是这样 学习了
skynothing
2013 年 1 月 30 日
@fanwei 高手呀。。学习
jinwyp
2013 年 2 月 5 日
// 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 年 2 月 6 日
mongoskin支持批量插入的...为嘛要each、要map? https://github.com/kissjs/node-mongoskin#insertdocs-options-callback
skynothing
2013 年 2 月 6 日
@heroicYang 请问有例子吗?没看懂。
heroicYang
2013 年 2 月 7 日
@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