【问题标题】:How to use javascript Promises for updating multiple docs in mongodb?如何使用 javascript Promises 更新 mongodb 中的多个文档?
【发布时间】:2016-12-22 22:59:22
【问题描述】:

您好,我正在编写一个更新 mongodb 数据库的脚本。我的脚本执行以下操作。

  1. 解析文件结构并为目录中的所有文件准备架构对象。
  2. 然后查询数据库并获取数据库中的文件文档。
  3. 然后我使用第 1 步和第 2 步中准备的数组循环查找合适的方法,即保存或更新。
  4. 断开数据库。

由于 mongodb API 的异步特性,我不得不使用 Promises。但我无法通过承诺来实现这一目标。以下是我的代码。

// a array that stores the file Json objects
var fileJsonArray = [];

//passing the filePath twice as one serves as the source for the icons and the other is the base location.
//Check the documentaion for the file for more details
directoryParser.parseDirectory(...);
//console.log(fileJsonArray);

//connect to db
var mongoose = mongoose || require('mongoose');
mongoose.Promise = require('bluebird');
var dbUrl = 'mongodb://'+ config.dbLocation + ':' + config.dbPort + '/' + config.dbName;
mongoose.connect(dbUrl);

// an array that contains all the promises
var promises = [];
//console.log(fileJsonArray);
//  get all the element
promises.push(File.find({}).exec()
    .catch(function(err){
        console.error('Error while getting all elements',err);
    })
    .then(function(err, allElements) {
        if(err) {
            console.error(err);
        } else {
            console.log(fileJsonArray);

            for (var i = 0; i < fileJsonArray.length; i++) {
                console.log(fileJsonArray[i].name);
                if(fileJsonArray[i] in allElements) {
                    var query = {name : fileJsonArray[i].name, tags: fileJsonArray[i].tags}
                        , update = {size : fileJsonArray[i].size, bmarkedasdeleted: true}
                        , options = {multi: false};
                    promises.push(File.update(query, update, options).exec());
                    allElements.splice(allElements.indexOf(fileJsonArray[i]),1);
                } else {
                    promises.push(fileJsonArray[i].save(function(err) {
                        if(err) {
                            console.error(fileJsonArray, err);
                        }
                    }));
                }
            }

            for (var i = 0; i < allElements.length; i++) {
                var query = {name : allElements[i].name, tags: allElements[i].tags}
                    , update = {bmarkedasdeleted: false}
                    , options = {multi: false};
                promises.push(File.update(query, update, options).exec());
            }
        }
    }));

    //console.log(promises);

    Promise.all(promises).then(function() {
        mongoose.disconnect();
        console.log('Disconnect Mongoose.');
    }).catch(function(err){
        console.log(err);
    });

现在我无法保存任何值,因为 find({}).exec() 中的 fileJsonArray 为空。

请指教。如果需要任何说明,也可以添加一些 cmets。

【问题讨论】:

  • 只是不明白你为什么使用promises.push(File.find({}).exec()。您应该使用 File.find({}).exec() 获取所有元素,然后使用 promise.all 并发执行。
  • 我这样做是因为它可以帮助我收集数组中的所有承诺,然后我可以使用该数组调用 promises.all

标签: javascript node.js mongodb mongoose promise


【解决方案1】:

File.find({}).exec()
    .then((allElements) => {
        var promises = [];
        for (var i = 0; i < fileJsonArray.length; i++) {
            if (fileJsonArray[i] in allElements) {
                var query = {name : fileJsonArray[i].name, tags: fileJsonArray[i].tags}
                    , update = {size : fileJsonArray[i].size, bmarkedasdeleted: true}
                    , options = {multi: false};
                promises.push(File.update(query, update, options).exec());
                allElements.splice(allElements.indexOf(fileJsonArray[i]), 1);
            } else {
                promises.push(fileJsonArray[i].save());
            }
        }

        for (var i = 0; i < allElements.length; i++) {
            var query = {name : allElements[i].name, tags: allElements[i].tags}
                , update = {bmarkedasdeleted: false}
                , options = {multi: false};
            promises.push(File.update(query, update, options).exec());
        }

        return Promise.all(promises);
    }).then(() => {
        mongoose.disconnect();
        console.log('Disconnect Mongoose.');
    }).catch((err) => {
        console.log(err);
    });

因为Promise.all 返回所有已解决的承诺。你应该先执行File.findpromise,然后再收集其他的promise。请记住,只有在 File.find 承诺解决后,您才能获得其他承诺。

【讨论】:

    猜你喜欢
    • 2017-09-22
    • 2020-03-18
    • 2019-05-22
    • 1970-01-01
    • 2010-12-16
    • 2019-03-04
    • 2019-09-19
    • 2019-05-25
    • 2019-02-21
    相关资源
    最近更新 更多