使用异步的Mongoose批量保存/更新每个只更新一些文档

时间:2018-05-14 07:51:51

标签: javascript node.js mongoose

我正在尝试使用用户提交的表单的内容执行批量更新。每次提交都会更新已提交文档的变量子集。似乎最终的回调基本上是在所有异步操作完成之前调用的,但我无法弄清楚如何解决它。我也用async.eachSeries尝试了这个,但错误是一样的。

    // updates is a list of object ids    
    Items.model.find ({
        _id: {$in: updates}
    })
        .exec (function (err, found) {
            console.log (found);
            // 'found' contains the expected submissions
            for (var i = 0; i < found.length; i++) {
                console.log (found [i]._id);
                found [i].category = ObjectId (req.body [found [i]._id]);
                found [i].state = 'submitted';
            }

            // 'found' now shows the desired updates correctly
            console.log (found);
            async.eachSeries (found, function (item, next) {
                console.log (item);
                //each item appears to contain the desired updates
                item.save (function (err) {
                    if (err) return next (err);
                    return next ();
                });
            }, function (err) {
                console.log (err);
                console.log ("done");
                return res.redirect ('/dataview/' + locals.app.name + "/" + req.body.page);
            });
        });

在上述所有内容的最后,如果我们重新访问该页面,实际上只会更新和存储一部分文档。我试图弄清楚原因,然后撕掉我的头发。

1 个答案:

答案 0 :(得分:0)

您可以使用async.eachOfSeries完成单次迭代而不是双重

// updates is a list of object ids    
Items.model.find({
        _id: {
            $in: updates
        }
    })
    .exec(function (err, found) {
        console.log(found);
        // 'found' contains the expected submissions
        async.eachOfSeries(found, function (item, i, next) {
            item.category = ObjectId(req.body[item._id]);
            item.state = 'submitted';
            console.log(item);
            //each item appears to contain the desired updates
            item.save(next);
        }, function (err) {
            console.log(err);
            console.log("done");
            return res.redirect('/dataview/' + locals.app.name + "/" + req.body.page);
        });
    });

但我建议您使用Promise.all功能并直接更新,而不是查找和更新

const itemList = [];
for (var i = 0; i < updates.length; i++) {
    itemList.push(Items.model.update({
        _id: updates[i]
    }, {
        $set: {
            state: 'submitted',
            category: ObjectId(req.body[updates[i]])
        }
    }));
}
Promise.all(itemList)
    .then((items) => {
        console.log('success');
        return res.redirect('/dataview/' + locals.app.name + '/' + req.body.page);
    })
    .catch((err) => {
        console.log('error ', err);
        return res.redirect('/dataview/' + locals.app.name + '/' + req.body.page);
    });