2015-08-25 2 views
2

Я пробовал модуль require, который является самоисключительной функцией Javascript и передаёт ему параметр, когда I require. «Обязательный» объект всегда говорит, что «объект не является функцией».Требуется модуль, который использует шаблон раскрывающего модуля

Возможно ли использовать следующий код, и если да, то где я ошибаюсь?

Модуль

var _ = require('lodash'); 
 

 
var userRepository = (function(userRecords) { 
 

 
    console.log(userRecords); 
 

 
    var findByUsername = function(username, cb) { 
 

 
    //find username in the userNameData 
 
    //this may have been retrieved from the DB or passed in as mock data from the tests 
 
    var user = _.find(userRecords, { 
 
     "email": username 
 
    }); 
 

 
    if (user) { 
 
     return cb(null, user); 
 
    } else { 
 
     return cb(null, null); 
 
    } 
 
    }; 
 

 
    return { 
 
    findByUserName: findByUsername 
 
    }; 
 

 
})(); 
 

 
module.exports = userRepository;

Использование в коде

var userData = require('../test/data/users.json'), 
 
    userRepository = require('../db/userRepository')(userData); 
 

 

 
describe('User Repository', function() { 
 
    describe('Find by username', function() { 
 
    it('should return a user record for <user> if the username <username> is found', function() { 
 
     var username = "[email protected]"; 
 
     var user = userRepository.findByUsername(username, function() {}); 
 
    }); 
 
    }); 
 
});

Заранее спасибо за любую помощь

ответ

1

userRepository - это IIFE, который возвращает объект, поэтому, когда вы его требуете, вы получаете этот объект, который, увы, не является функцией.

Я вижу, что вы пытаетесь вызвать findByUserName, который действительно является «общественная» функция на этом объекте, просто измените ваш требуйте линию следующее:

userRepository = require('../db/userRepository'); 

После этой линии, userRepository будет объект, возвращаемый вами IIFE. Затем вы можете позвонить userRepository.findByUserName() (как вы в своем примере) без каких-либо дополнительных изменений кода.

Если вы хотите userRepository принять параметр userRecord в качестве параметра (согласно вашему комментарию), не используйте функцию самозапускания, просто экспортируйте функцию, которая в настоящее время сама вызывает вызов.

(Интуитивно: если вы хотите, чтобы userRecord поставлялся извне модуля, вы не можете использовать эту функцию самостоятельно, вам нужно экспортировать эту функцию, чтобы сделать ее доступной для пользователей вашего модуля - так, чтобы они могут назвать это с userRecord, что у них есть.)

+0

Я бы хотел передать параметр 'require'. то есть я хочу передать 'userRecords' в (немного как инъекция зависимостей). Поэтому я могу сделать модуль более надежным. Можно ли сделать это? Спасибо –

+0

Также, пожалуйста, не могли бы вы объяснить, что такое IIFE, спасибо –

+0

@JonHunter Тогда не делайте его самоисполняемой функцией, экспортируйте функцию, которая возвращает этот объект.(Если вам нужно 'userRepository', чтобы он пришел из внешнего источника, вы не можете вызывать эту функцию внутри своего модуля, поэтому его не следует вызывать самостоятельно) [IIFE] (https://en.wikipedia.org/wiki/Immediately-invoked_function_expression) – doldt

2

Вы можете изменять модуль декларации функционировать isntead

var userRepository = function(userRecords) { 
    //private props 

    return { 
    //return object 
    }; 

}; 

, то она может быть вызвана с синтаксисом вы используете - require(MODULE_NAME)(data);

1

путь ваш код в настоящее время настроен, вы экспортируете userRepository, который фактически равен значению возврата вашей анонимной функции {findByUserName: findByUsername}. Это объясняет, почему вы получаете ошибку Object is not a function.

Если вы хотите, чтобы ваш require принимал параметр, он должен был быть функцией, а не объектом.

Смежные вопросы