【问题标题】:Requiring a module that uses the revealing module pattern需要一个使用显示模块模式的模块
【发布时间】:2015-08-25 18:18:33
【问题描述】:

我正在尝试 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() {});
    });
  });
});

提前感谢您的帮助

【问题讨论】:

    标签: javascript node.js revealing-module-pattern


    【解决方案1】:

    您可以将模块声明更改为函数 istead

    var userRepository = function(userRecords) {
      //private props
    
      return {
        //return object
      };
    
    };
    

    然后可以使用您使用的语法调用它 - require(MODULE_NAME)(data);

    【讨论】:

      【解决方案2】:

      userRepository 是一个 IIFE,它返回一个对象,所以当你需要它时,你会收到这个对象——唉,它不是一个函数。

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

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

      在这一行之后,userRepository 将是您的 IIFE 返回的对象。然后您可以调用userRepository.findByUserName()(就像您在示例中一样),而无需对您的代码进行任何进一步的修改。

      如果您希望userRepositoryuserRecord 作为参数(根据您的评论),请不要使用自调用函数,只需导出当前自调用的函数。

      (直观地说:如果你想从模块外部提供userRecord,你不能让这个函数自调用,你需要导出函数本身以使其对你的模块的用户可用- 这样他们就可以使用他们拥有的userRecord 调用它。)

      【讨论】:

      • 我想将参数传递给require。即我想传递userRecords in(有点像依赖注入)。这样我就可以使模块更具可测试性。是否有可能做到这一点?谢谢
      • @JonHunter 然后不要让它成为一个自执行函数,导出返回这个对象的函数。 (如果你需要userRepository来自外部源,你不能在你的模块内部调用这个函数,所以它不应该是自调用的)IIFE
      【解决方案3】:

      您的代码当前设置的方式,您正在导出userRepository,这实际上等于您的匿名函数{findByUserName: findByUsername}的返回值。这解释了为什么您会收到错误 Object is not a function

      如果您希望 require 接受参数,则它必须是函数而不是对象。

      【讨论】:

        猜你喜欢
        • 2014-05-30
        • 1970-01-01
        • 2012-07-09
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多