【问题标题】:How to create callback post saving an array of objects?如何在保存对象数组后创建回调?
【发布时间】:2012-09-26 11:26:15
【问题描述】:

假设我在函数中有以下内容:

exports.addnames = function(req, res) {
    var names = ["Kelley", "Amy", "Mark"];

    for(var i = 0; i < names.length; i++) {
        (function (name_now) {
            Person.findOne({ name: name_now},
                function(err, doc) {
                    if(!err && !doc) {
                        var personDoc = new PersonDoc();
                        personDoc.name = name_now;
                        console.log(personDoc.name);
                        personDoc.save(function(err) {});
                    } else if(!err) {
                        console.log("Person is in the system");
                    } else {
                        console.log("ERROR: " + err);
                    }
                }
            );   
        )(names[i]);
    }

我的问题是保存名称后,我想返回结果:

Person.find({}, function(err, doc) {    
    res.json(200, doc);
})

虽然我有一个名称回调,但似乎最后一个代码块 (Persons.find({})) 在保存所有名称的调用完成之前执行......因此当用户转到浏览器中的 url,“doc”为空...有什么方法可以确保在 for 循环完成后调用 Persons.find({})?

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    执行此类操作的最简单方法是使用一个异步库,例如恰当命名的 async,可以在 https://github.com/caolan/async 找到。

    如果您有一个想要保存并在完成后返回的名称列表,它看起来像:

    // save each of the names asynchronously
    async.forEach(names, function(name, done) {
        Person.findOne({name: name},
            function(err, doc) {
                // return immediately if there was an error
                if(err) return done(err);
    
                // save the person if it doesn't already exist
                if(!doc) {
                    var personDoc = new PersonDoc();
                    personDoc.name = name;
                    console.log(personDoc.name);
    
                    // the async call is complete after the save completes
                    return personDoc.save(done);
                } 
    
                // or if the name is already there, just return successfully
                console.log("Person is in the system");
                done();
            }
        );           
    },
    // this function is called after all of the names have been saved
    // or as soon as an error occurs
    function(err) {
        if(err) return console.log('ERROR: ' + err);
    
        Person.find({}, function(err, doc) {    
            res.json(200, doc);
        })
    
    });
    

    【讨论】:

    • 这意味着 done 由于某种原因没有被调用(我认为 1 分钟是 async 超时)。您需要缩小问题的范围 - 您可以从完全注释掉 Person.findOne 开始,然后立即致电 done();。应立即调用最终函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    相关资源
    最近更新 更多