【问题标题】:Mongoose calling save callback before DB write?猫鼬在数据库写入之前调用保存回调?
【发布时间】:2015-05-09 16:50:00
【问题描述】:

我正在使用 mongoose 和 node,我有一些功能允许用户上传 CSV,然后将数据放入 mongo。

我正在尝试防止上传重复的用户名。为了缓解这种情况,我调用 findOne 并在将条目保存到数据库之前查找用户名,如果找到用户名,它应该调用 async 的 callback() 并进入下一次迭代。

我有一个保存回调,我希望只在数据在数据库中时调用它,在这个回调中我调用callback()

从我的控制台日志中,每个重复的 findOne 都显示为 null,但数据实际上正在写入数据库(如果我尝试在 csv 中上传更多重复项,那么一切都按预期工作)。

几乎就好像在数据库写入实际发生之前调用了保存回调,因此下一次调用没有找到重复项,我对 mongo 如何写入数据库有一些基本的误解还是我忽略了一些明显的东西...

admin.post('/upload', function(req, res) {
if(req.files.file) {
    var file = req.files.file;

    fs.readFile(file.path, 'utf8', function(err, data) {
        if(err) return res.json({error: err});

        csv.parse(data, function(err, parsed) {
            // remove header
            if(!parsed) {
                return;
            }

            parsed.splice(0, 1);

            var headers = ['auth', 'sid', 'fl', 'dd'];

            async.each(parsed, function(row, callback) {
                var seed = {};

                for(var i = 0; i < 4; i++) {
                    if(row[i] && row[i].trim() !== '') {
                        seed[headers[i]] = row[i].trim();
                    }
                }

                if(seed.user && seed.password) {
                    User.findOne({username: seed.user}, function(err, result) {
                        if(err) {
                            console.log(err);
                            return res.json({error: err});
                        }

                        console.log(result);

                        if(!result) {
                            console.log('creating user');
                            var user = new User({
                                username: seed.user,
                                password: User.generateHash(seed.password),

                            });

                            user.save(function(err) {
                                if(err){
                                    return res.json({error: err});
                                }

                                console.log('SAVED CALLING CB');
                                callback();
                            });
                        } else {
                            callback();
                        }
                    });
                } else {
                    callback();
                }
            }, function() {
                return res.json({success: true});
            });
        });
    });
}
});

【问题讨论】:

    标签: mysql node.js mongodb csv callback


    【解决方案1】:

    您可能在其中遇到了争用情况,这似乎是因为您说您的脚本在第二次运行时有效。

    由于async.each 并行运行,如果重复的用户名在 CSV 文件中相邻的行中,则可能在第一个 save 之前进行了两次 findOne 调用。

    我建议您使用唯一索引强制数据库的唯一性。它也将更具性能(每个用户只需访问数据库一次),您只需处理唯一约束错误。

    【讨论】:

    • 我现在觉得自己像个白痴,我把异步和异步系列混在一起了。非常有道理,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    • 2014-11-16
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2019-06-09
    相关资源
    最近更新 更多