【问题标题】:this.find(...) never reaches callback within static methodthis.find(...) 永远不会在静态方法中到达回调
【发布时间】:2015-02-14 08:08:31
【问题描述】:

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

我基本上是在尝试做 this guy 正在尝试做的事情(AFAIK,应该可以工作——这令人沮丧)

为什么FriendshipSchema.statics.getFriends 中的find(...) 从未到达其回调?

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

accounts.js内:

  1. 需要'friends-of-friends'模块(加载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. 定义调用this.getFriendsAccountSchema.statics.search
    由于this在编译后引用Account模型,并且由于插件添加了schema.statics.getFriends,因此在AccountSchema.statics.search中调用this.getFriends将调用schema.statics.getFriends,如friends-of-friends/plugin.js中定义的那样,它将调用@987654342 @(由 friends-of-friends/friendship.js 中的 FriendshipSchema.statics.getFriends 定义)调用 this.find(...) 应转换为 Friendship.find(...)`
  4. 在检索到一个帐户文档后,我调用了account.search('foo', function (...) {...});,但正如您在FriendshipSchema.statics.getFriends 中看到的那样,find 方法执行了,但它的回调从未被调用,程序挂起:(

我没有收到任何错误,所以我知道这是一个逻辑问题,但我不确定为什么事情会在它们所在的地方挂起......

编辑 - 请参阅下面的答案,我还需要编译模型,然后才能调用 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的人,请您赐教您的推理或建议以改进我的问题。

标签: javascript node.js mongoose mongoose-plugins


【解决方案1】:

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

在我的主应用程序中,我需要来自app/node_modules/mongoose 的猫鼬,而我的friends-of-friends 模块——在package.json 中将猫鼬列为依赖项——需要来自app/node_modules/friends-of-friends/node_modules/mongoose 的猫鼬,它创建了两个单独的猫鼬实例,这使事情无法正常工作。

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

应该有RTFM

app/
|   lib/
|   node_modules/ 
|   |   mongoose/             <-- main app required here
|   |   friends-of-friends/
|   |   |   node_modules/     <-- deleted; mongoose was only dep
|   |   |   |   mongoose/     <-- friends-of-friends module required here
|   server.js

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 2019-07-24
    • 1970-01-01
    相关资源
    最近更新 更多