需要使用揭示模块模式的模块

3

我想尝试使用require来调用一个自执行的Javascript函数,并在调用时传递一个参数。但是,当我使用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 = "test@testing.com";
      var user = userRepository.findByUsername(username, function() {});
    });
  });
});

感谢您提前的任何帮助

3个回答

2
您可以将模块声明更改为函数。
var userRepository = function(userRecords) {
  //private props

  return {
    //return object
  };

};

那么它可以通过你使用的语法调用 - require(MODULE_NAME)(data)


1

userRepository 是一个 IIFE,返回一个对象。当您需要它时,会收到此对象,但很遗憾,它不是一个函数。

我看到您正在尝试调用 findByUserName,这确实是该对象上的“公共”函数,只需将您的 require 行更改为以下内容:

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

在这行代码之后,userRepository 将会是你的 IIFE 返回的对象。然后,你可以直接调用 userRepository.findByUserName()(就像你的示例中一样),而不需要对你的代码进行任何其他修改。
如果你想让 userRepository 接受 userRecord 作为参数(根据你的注释),那么就不要使用自执行函数,只需导出当前正在自执行的函数即可。
直观地说:如果你想从模块外部提供 userRecord,你不能让这个函数自我调用,而是需要导出函数本身,以使它对你的模块的用户可用 - 这样他们就可以使用他们拥有的 userRecord 调用它。

我想通过require传递一个参数。也就是说,我想将userRecords传递进去(有点像依赖注入)。这样我就可以使模块更易于测试。这种做法可行吗?谢谢。 - Jon Hunter
@JonHunter 那就不要把它做成自执行函数,导出返回该对象的函数即可。(如果您需要从外部源获取userRepository,则不能在模块内调用此函数,因此它不应该是自调用的)IIFE - doldt

1
您的代码目前的设置方式是导出userRepository,实际上等于匿名函数{findByUserName: findByUsername}的返回值。这就解释了为什么会出现错误Object is not a function
如果您想让require接受一个参数,那么它必须是一个函数而不是一个对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接