使用 Mongoose.js Model.Remove(conditions, callback) - 删除成功但未调用回调

Using Mongoose.js Model.Remove(conditions, callback) - remove successful but callback not being called

我已经简化为以下最基本的可能版本...

    UserModel.remove({ }, function (err) {
        console.log("inside callback");
    })

我已确认记录已被删除,但从未调用回调。

我使用

成功添加了文档
var user = new UserModel(req.body);

user.save(function (err) {
    if (err) {
        return (next(err));
    } else {
        res.json(user);
    }
});

我设置了一些测试并验证了记录是使用 mongodb shell 插入的。然后验证当我调用 remove 时它们被删除了,所以我知道数据库连接是好的。除了 remove 永远不会调用回调之外,一切都按预期工作。我什至在保存回调中放了一些 console.log 语句,它按预期工作。

我正在使用节点 0.10.33、猫鼬 4.0.4 和 mongodb 2.6.6

对这里可能发生的事情有什么想法吗?

提前致谢,

杰夫

好的,正如预期的那样,系统要求我提供更多背景信息。以上是为了保持简单。 UserModel.remove 调用的上下文如下...

var UserModel = require('mongoose').model('User');

exports.create = function (req, res, next) {
    var user = new UserModel(req.body);

    user.save(function (err) {
        if (err) {
            return (next(err));
        } else {
            res.json(user);
        }
    });
};

exports.list = function (req, res, next) {
    UserModel.find({}, function (err, users) {
        if (err) {
            return next(err);
        } else {
            res.json(users);
        }
    });
};

exports.delete = function (req, res, next) {

        UserModel.remove({ }, function (err) {
            console.log("finished deleting single user");

        })

}

mongoose.js 是...

var config = require('./config'),
    mongoose = require('mongoose');

module.exports = function (){
    var db = mongoose.connect(config.dbUri);

    require('../app/models/user.server.model');

    return db;
}

config.js 是...

module.exports = {
    sessionSecret: 'developmentSessionSecret',
    dbUri: 'mongodb://localhost/test'
};

最后,user.server.model.js 是...

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var UserSchema = new Schema({
    firstName: String,
    lastName: String,
    email: String,
    username: String,
    password: String
});

mongoose.model('User', UserSchema);

这也是我的 mocha 测试文件,以防万一...

var boot = require('../server').boot,
    shutdown = require('../server').shutdown,
    port = require('../server').port,
    superagent = require('superagent'),
    expect = require('chai').expect,
    baseUrl = 'http://localhost:' + port,
    Utility = require('../Utility');

describe('server', function () {

    before(function () {
        boot();
    });



    describe('homepage', function () {
        it('should respond to GET', function (done) {

            superagent
                .get(baseUrl)
                .end(function (err, res) {
                expect(res.status).to.equal(200);
                done();
            })
        })
    });

    describe('/users', function () {
        var url = baseUrl + "/users";

        var returnedJson,
            id;

        it('should respond when a JSON message is posted that matches the schema', function (done) {

            superagent
                    .post(url)
                    .send({ 'firstName': 'Jeff', 'lastName': 'Hegedus', 'email': 'jhegedus@centrifugeit.com', 'username': 'jhegedus', 'password': 'testpassword' })
                    .end(function (err, res) {
                expect(res.status).to.equal(200);
                returnedJson = res.text;
                done();
            })

        })

        it('should return the result of the insert with the _id populated', function () {

            var returnedObject = JSON.parse(returnedJson);
            id = returnedObject._id;
            expect(id).to.be.ok;

        })



        it('should respond to get', function (done) {
            superagent
                    .get(url)
                    .end(function (err, res) {
                expect(res.status).to.equal(200);
                done();
            })
        });


        // Delete by id
        it('should allow delete of the user created', function () {

            superagent
                    .del(url)
                    .set("id", id)
                    .end(function (err, res) {
                console.log("in response from delete");
                expect(res.status).to.equal(200);
                returnedJson = res.text;
                console.log("deleted " + returnedJson);
                done();
            })

        })


    })




    after(function () {
        shutdown();
    });

});

哦,如果你想知道,我正在处理的真正删除功能是当前状态

exports.delete = function (req, res, next){
    var id = req.get("id");
    console.log("deleting id = " + id);

    if (id == null) {
        console.log("deleting all users");
        UserModel.remove({}, function (err, users){
            if (err) {
                return next(err);
            } else {
                res.json(users);
            }
        })
    } else {

        UserModel.remove({ "_id": id }, function (err) {
            console.log("deleting single user");
            if (err) {
                return next(err);
            } else {
                res.json(users);
            }
        })

    }
}

我知道比 post 简单版本更好。一半想 post 整个事情 github 这样你就可以看到它们是如何组合在一起的。 ;-)

当您不向测试回调传递 done 参数时,mocha 不会等待其完成,但仍会执行它。你做到了:

it('should allow delete of the user created', function () {
  // your test
});

所以,这就是为什么你的用户数据被删除,但你在控制台中看不到任何记录:正在调用 delete 路由,正在执行 UserModel.remove,但是mocha 执行结束,无需等待其 return。只需传递 done 回调:

it('should allow delete of the user created', function (done) {
  // your test
});