Node.js Mongoose pre.save()在创建记录时生成特定代码时出现问题

Node.js Mongoose pre.save()在创建记录时生成特定代码时出现问题,node.js,mongoose,mongoose-schema,Node.js,Mongoose,Mongoose Schema,我有一个具有以下属性的Mongo集合: { "_id" : ObjectId("384f1f06f72cc1b566e32f98"), "num" : 41, "product" : ObjectId("5c8921d8f9f7be241c0b02cf"), "data" : { "phone" : "123123123", "email" : "email@email.com", "name" : "John",

我有一个具有以下属性的Mongo集合:

{
    "_id" : ObjectId("384f1f06f72cc1b566e32f98"),
    "num" : 41,
    "product" : ObjectId("5c8921d8f9f7be241c0b02cf"),
    "data" : {
        "phone" : "123123123",
        "email" : "email@email.com",
        "name" : "John",
        "_id" : ObjectId("5ca34689ac024b579991fe26")
    },
    "generatedCode": "01-1FCS3";
}
根据产品的类型(您可以看到它是一个对象),我希望在每次创建新元素时生成不同的代码

    ProductSchema.pre('save', function(next) {

        if ((typeof this.generatedCode === 'undefined') || !this.generatedCode) {

            ProductSchema.find({_id: this.product}, function(error, existingProduct) {
                if (error) {
                    next(Error(error));
                }
                else {

                    if (existingProduct.length > 0) {

                        console.log("Type of product: "+ existingProduct[0].type);
                        generateCode(this,existingProduct[0].type).then(function(doc) {
                            console.log('Code generated:' + doc.generatedCode);
                            next();
                        }, function(err) {
                            console.error(err);
                            next(err);
                        });
                    }
                    else {
                        next(new Error("Error: Not found."));
                    }

                }
            });


    } else {
        next();
    }
});

    function generatedCode(doc,productType){
        var deferred = q.defer();
        try {
            console.log("Product type = "+ invoiceType);
            var ObjectId = require('mongoose').Types.ObjectId;    
            var generatedCode = '';

            switch(productType) {
                case 'TYPE1':
                    generatedCode = 'COD01-'+ random(5);
                break;
                case 'TYPE2':
                    generatedCode = 'COD02-'+ random(5);
                break;
                default: // other types
                    generatedCode = 'COD03-'+ random(5);
            }

            console.log("generatedCode = "+ generatedCode);
            var InvoiceModel = mongoose.model('Invoice', InvoiceSchema);

            // check that there are no records with that code

            InvoiceModel.find({generatedCode: generatedCode}, function(err, existingInvoice) {
                console.log('Find: '+ generatedCode);

                if(err) {
                    console.log(err);
                    deferred.reject(err);
                }

                if(existingInvoice.length > 0) {
                    console.log('Alredy exists ' + generatedCode + ' in db');
                    generatedCode(doc,productType).then(function(doc) {
                        deferred.resolve(doc);
                    }, function(err) {
                        deferred.reject(err);
                    });
                }
                else {
                    console.log("generatedCode = "+ generatedCode);
                    console.log("Doc = "+ doc);
                    doc.generatedCode = generatedCode;
                    deferred.resolve(doc);
                }
            });
        }
        catch(exception) {
            console.error(exception);
            deferred.reject(new Error(exception.message));
        }
        return deferred.promise;
    }
我不知道为什么会出现错误,但在“doc.generatedCode=generatedCode;”行中返回null,似乎doc不存在,我不明白是什么失败了

我将向您展示调试:

Type of product: GENERIC
Product type = GENERIC
generatedCode = COD03-8KORD
Find: COD03-8KORD
generatedCode = COD03-8KORD
Doc = null
[ERROR] (node.js:496) -> uncaughtException: Cannot set property 'code' of null

当您在
回调
函数中时,
的值会发生变化。这里的代码也是如此。执行
ProductSchema.find
并尝试访问其中的
this
时,该值会更改。您需要保存对外部实际值的引用

ProductSchema.pre('save', function(next) {

    if ((typeof this.generatedCode === 'undefined') || !this.generatedCode) {

        var that = this; // here create a reference to "this"

        ProductSchema.find({_id: this.product}, function(error, existingProduct) {

            ..
            ..

                // generateCode(this,existingProduct[0].type).then(function(doc) { // YOUR OLD CODE
                generateCode(that,existingProduct[0].type).then(function(doc) { // here, change "this" to "that" which is the actual reference of your object
            ..
            ..

很好用!!谢谢你的帮助,我已经解决了这个问题:)