在mongodb中制作butch upsert:回调永远不会被解雇

时间:2014-09-03 13:20:28

标签: node.js mongodb asynchronous

我有一组带有唯一_id的文档,我想将它们插入到我的数据库中。其中一些已经在db中,对于那些我想要更新数组属性(将数组推入项目)。所有这一切我都需要进行asyncronuosly,所以在插入/更新之后我想把回复(回调)写回客户端而不是所有ok或写错误。在谷歌搜索主题后,我发现了这个solution with async module我试图为我的情况实现它。现在我的代码看起来像这样:

function processUsers(arr, listName, callback) {

    var users = global.db.collection('vkusers');
    var q = async.queue(function(task, cb) {
        console.log('upsert butch');
        users.insert(task.doc, function(err, doc) {
            if (err) {
                users.update({
                    _id : task.doc._id
                }, {
                    $addToSet : {
                        mLists : listName
                    }
                }, function(error, result){ console.log(error); console.log(result); });
            }

        });

    }, arr.length);

    for ( var doc in arr) {
        q.push({
            doc : arr[doc]
        }, function(err) {
            if (err)
                callback(err, null);
        })
    }
    q.drain = function() {
        // this is the queue's callback, called when the queue is empty,
        // i.e. when all your documents have been processed.
        console.log('drain');
        callback(null, { result: "success", upserted: arr.length });
    }

}

回调有签名回调(错误,结果),arr - 我的文档数组。我已经测试了它,并且数据库一切正常,我得到了正确的结果。但回调,q.drain从未被解雇!

1 个答案:

答案 0 :(得分:0)

插入/更新完成后,您需要在代码中调用async.queue的回调(cb)。像这样:

var q = async.queue(function(task, cb) {
    console.log('upsert butch');
    users.insert(task.doc, function(err, doc) {
        if (err) {
            users.update({
                _id : task.doc._id
            }, {
                $addToSet : {
                    mLists : listName
                }
            }, function(error, result) { 
                console.log(error); 
                console.log(result); 

                cb(error); // Update finished; call cb and pass in "error" so that it can bubble up if it exists
            });
        } else {
            cb(); // Insert succeeded; call cb
        }
    });

}, arr.length);