this.find(...)永远不会在静态方法中达到回调

时间:2014-12-16 04:17:48

标签: javascript node.js mongoose mongoose-plugins

我正在开发一个模块,它将基于友谊的关系添加到Schema。

我基本上都在努力做this guy试图做的事情(AFAIK应该有效 - 这是令人沮丧的)

为什么find(...)中的FriendshipSchema.statics.getFriends永远不会收到回调?

编辑 - 请允许我解释预期的执行流程......

accounts.js内:

  1. 需要“朋友的朋友”模块(加载friends-of-friends/index.js
    1. 需要friends-of-friends/friendship.js导出创建FriendshipSchema的函数,添加静态方法,返回Friendship模型。
    2. 需要friends-of-friends/plugin.js导出mongoose插件,该插件将静态和实例方法添加到`AccountSchema。
  2. 使用FriendsOfFriends.plugin(请参阅friends-of-friends/index.js)插入friends-of-friends/plugin.js
  3. 中的功能
  4. 定义调用AccountSchema.statics.search的{​​{1}} 由于this.getFriends模型在编译后会引用this模型,并且由于插件已添加Account,因此在schema.statics.getFriends内调用this.getFriends会调用AccountSchema.statics.search正如schema.statics.getFriends中所定义的那样,会调用friends-of-friends/plugin.jsFriendship.getFriendsFriendshipSchema.statics.getFriends定义)调用friends-of-friends/friendship.js,该this.find(...)应转换为Friendship.find(... )`
  5. 检索帐户文档后,我拨打account.search('foo', function (...) {...});,但正如您在FriendshipSchema.statics.getFriends中看到的那样,find方法会执行,但其回调永远不会被调用,程序会挂起:(
  6. 我没有收到任何错误,所以我知道这是一个逻辑问题,但我不确定为什么事情会被挂起来......

    编辑 - 请参阅下面的答案,我还需要先编译模型,然后再打电话给find

    account.js

    var mongoose = require('mongoose'),
        passportLocalMongoose = require('passport-local-mongoose');
    
    var FriendsOfFriends = require('friends-of-friends')();
    
    // define the AccountSchema
    // username, password, etc are added by passportLocalMongoose plugin
    var AccountSchema = new mongoose.Schema({
        created:        { type: Date,       default:    Date.now                    },
        profile: {
            displayName:    { type: String,     required:   true,       unique : true,  index: true     },
            firstName:      { type: String,     required:   true,       trim: true,     index: true     }, 
            lastName:       { type: String,     required:   true,       trim: true,     index: true     }, 
        }
    });
    
    // plugin the FriendsOfFriends plugin to incorporate relationships and privacy
    AccountSchema.plugin(FriendsOfFriends.plugin, FriendsOfFriends.options);
    
    AccountSchema.statics.search = function (userId, term, done) {
        debug('search')
    
        var results = {
                friends: [],
                friendsOfFriends: [],
                nonFriends: []
            },
            self=this;
    
        this.getFriends(userId, function (err, friends) {
    
           // never reaches this callback!
    
        });
    
    };
    
    AccountSchema.methods.search = function (term, done) {
        debug('method:search')
        AccountSchema.statics.search(this._id, term, done);
    };
    
    module.exports = mongoose.model('Account', AccountSchema);
    

    朋友-的-朋友/ index.js

    /**
     * @author  Jeff Harris
     * @ignore
     */
    
    var debug = require('debug')('friends-of-friends');
        friendship = require('./friendship'),
        plugin = require('./plugin'),
        privacy = require('./privacy'),
        relationships = require('./relationships'),
        utils = require('techjeffharris-utils');
    
    module.exports = function FriendsOfFriends(options) {
    
        if (!(this instanceof FriendsOfFriends)) {
          return new FriendsOfFriends(options);
        } 
    
        var defaults = {
            accountName:    'Account',
            friendshipName: 'Friendship', 
            privacyDefault: privacy.values.NOBODY
        };
    
        this.options = utils.extend(defaults, options);
    
        /**
         * The Friendship model
         * @type {Object}
         * @see  [friendship]{@link module:friendship}
         */
        this.friendship = friendship(this.options);
    
        /**
         * mongoose plugin
         * @type {Function}
         * @see  [plugin]{@link module:plugin}
         */
        this.plugin = plugin;
    
        debug('this.friendship', this.friendship);
    
    };
    

    朋友的朋友/ friendship.js

    var debug = require('debug')('friends-of-friends:friendship'),
        mongoose = require('mongoose'),
        privacy = require('./privacy'),
        relationships = require('./relationships'),
        utils = require('techjeffharris-utils');
    
    module.exports = function friendshipInit(options) {
    
        var defaults = {
            accountName:    'Account',
            friendshipName: 'Friendship',
            privacyDefault: privacy.values.NOBODY
        };
    
        options = utils.extend(defaults, options);
    
        debug('options', options);
    
        var ObjectId = mongoose.Schema.Types.ObjectId;
    
        var FriendshipSchema = new mongoose.Schema({
            requester: { type: ObjectId, ref: options.accountName, required: true, index: true },
            requested: { type: ObjectId, ref: options.accountName, required: true, index: true },
            status: { type: String, default: 'Pending', index: true},
            dateSent: { type: Date, default: Date.now, index: true },
            dateAccepted: { type: Date, required: false, index: true }
        });
    
        ...
    
        FriendshipSchema.statics.getFriends = function (accountId, done) {
            debug('getFriends')
    
            var model = mongoose.model(options.friendshipName, schema),
                friendIds = [];
    
            var conditions = { 
                '$or': [
                    { requester: accountId },
                    { requested: accountId }
                ],
                status: 'Accepted'
            };
    
            debug('conditions', conditions);
    
            model.find(conditions, function (err, friendships) {
                debug('this callback is never reached!');
    
                if (err) {
                    done(err);
                } else { 
                    debug('friendships', friendships);
    
                    friendships.forEach(function (friendship) {
                        debug('friendship', friendship);
    
                        if (accountId.equals(friendship.requester)) {
                            friendIds.push(friendship.requested);
                        } else {
                            friendIds.push(friendship.requester);
                        }
    
                    });
    
                    debug('friendIds', friendIds);
    
                    done(null, friendIds);
                }
    
            });
    
            debug('though the find operation is executed...');
        };
    
        ...
    
        return mongoose.model(options.friendshipName, FriendshipSchema);
    };
    

    朋友-的-朋友/ plugin.js

    var debug = require('debug')('friends-of-friends:plugin'),
        mongoose = require('mongoose'),
        privacy = require('./privacy'),
        relationships = require('./relationships'),
        utils = require('techjeffharris-utils');
    
    module.exports = function friendshipPlugin (schema, options) {
    
        var defaults = {
            accountName:    'Account',
            friendshipName: 'Friendship',
            privacyDefault: privacy.values.NOBODY
        };
    
        options = utils.extend(defaults, options);
    
        var Friendship = mongoose.model(options.friendshipName);
    
        ...
    
        schema.statics.getFriends = function (accountId, done) {
            debug('getFriends')
    
            var model = mongoose.model(options.accountName, schema);
    
            var select = '_id created email privacy profile';
    
            Friendship.getFriends(accountId, function (err, friendIds) {
                if (err) {
                    done(err);
                } else {
                    model.find({ '_id' : { '$in': friendIds } }, select, done);
                }
            });
        };
    
        ...
    
        schema.methods.getFriends = function (done) {
            schema.statics.getFriends(this._id, done);
        };
    };
    

1 个答案:

答案 0 :(得分:0)

问题与需要哪种猫鼬实例有关。

在我的主应用程序中,我要求来自app/node_modules/mongoose的猫鼬而我的friends-of-friends模块 - 已将mongoose列为package.json中的依赖项 - 需要来自{{1}的猫鼬},它创建了两个单独的mongoose实例,这使得一些东西不起作用。

我删除了mongoose作为依赖项,删除了嵌套的app/node_modules/friends-of-friends/node_modules/mongoose文件夹,并且使用了vioala,它再次起作用了:)

应该有RTFM

node_modules