V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
skynothing
V2EX  ›  Node.js

node-mongoskin如何批量添加?

  •  
  •   skynothing · 2013-01-29 15:45:42 +08:00 · 4664 次点击
    这是一个创建于 4323 天前的主题,其中的信息可能已经有所发展或是发生改变。
    因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相同的记录。
    12 条回复    1970-01-01 08:00:00 +08:00
    ljbha007
        1
    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
        2
    skynothing  
    OP
       2013-01-29 16:39:12 +08:00
    @ljbha007 你的意思我明白了。不过你的回答还是没解决问题。
    ljbha007
        3
    ljbha007  
       2013-01-29 16:56:19 +08:00   ❤️ 1
    @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
        4
    skynothing  
    OP
       2013-01-29 17:06:13 +08:00
    @ljbha007 太牛了。谢谢!
    fanwei
        5
    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
        6
    fanwei  
       2013-01-29 18:34:29 +08:00   ❤️ 1
    少写了个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
        7
    ljbha007  
       2013-01-29 19:25:26 +08:00
    @fanwei 原来是这样 学习了
    skynothing
        8
    skynothing  
    OP
       2013-01-30 16:19:00 +08:00
    @fanwei 高手呀。。学习
    jinwyp
        9
    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
        10
    heroicYang  
       2013-02-06 12:35:17 +08:00
    mongoskin支持批量插入的...为嘛要each、要map? https://github.com/kissjs/node-mongoskin#insertdocs-options-callback
    skynothing
        11
    skynothing  
    OP
       2013-02-06 18:12:44 +08:00
    @heroicYang 请问有例子吗?没看懂。
    heroicYang
        12
    heroicYang  
       2013-02-07 16:05:57 +08:00   ❤️ 1
    @skynothing 第一个参数是你要插入的文档对象(或数组),第二个参数是一些可选项,如果想在第三参数即回调函数 callback 中取到插入的文档,可选项中请传入 { safe: true }。这样 callback 会传入两个参数:err 和 records,records即为插入之后的文档对象数组。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   992 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:00 · PVG 04:00 · LAX 12:00 · JFK 15:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.