从模块中调用 Node.js 模块函数

Posted

技术标签:

【中文标题】从模块中调用 Node.js 模块函数【英文标题】:Calling a Node.js module function from within the module 【发布时间】:2018-01-28 18:24:18 【问题描述】:

我正在尝试编写一个节点模块来清理我的代码并将其分离到不同的文件中。

考虑下面的代码:

module.exports = 
    Hello : function(request, reply) 
        return reply("Hello " + World());
    ,
    World : function() 
        return "World";
    

如果我导入上述模块并将 Hello 函数用作特定路由的处理程序,则会收到 HTTP 500 内部服务器错误。

如果我将 Hello 函数更改为

,我已将问题缩小到对 World() 的调用
Hello : function(request, reply) 
    return reply("Hello World");

然后它工作正常,所以它似乎在从导出对象中调用另一个函数时被绊倒了

有谁知道为什么会发生这种情况以及如何解决?

【问题讨论】:

jsfiddle.net/rc62tuw8 斯坦格。它可以解决这个问题。附加,但是我的应用程序似乎不喜欢它 @Michael:这取决于Hello 的调用方式。如果它作为导出对象的方法调用,this 将不会引用该对象。 你的myModule.Hello function..是从哪里来的? 它是从我的主 app.js 文件中调用的,带有以下 server.route( method: 'GET', path: '/user/new/q', handler: testy.你好 );似乎有些地方不太对劲,但 Ahmads 的回答效果很好 【参考方案1】:

您需要将this 添加到您对World() 的调用中 -

module.exports = 
    Hello : function(request, reply) 
        return reply("Hello " + this.World());
    ,
    World : function() 
        return "World";
    

World 是导出对象的一个​​属性,而不是可访问范围内的变量——因此您需要指定该函数属于this

【讨论】:

我也是这么想的,但是它没有效果 - 我仍然得到一个 HTTP 500 出于好奇,reply 是在哪里定义的? 只有在对模块执行Hello 函数时才有效,例如someModule.Hello()。在为 Web 服务器导出回调函数时,这种情况不太可能发生。【参考方案2】:

你应该这样称呼它:

module.exports = 
    Hello: function(request, reply) 
        return reply("Hello " + module.exports.World());
    ,
    World: function() 
        return "World";
    

如果您的目标是更简洁的代码,我建议您将代码更改为:

function World() 
  return "World";

function Hello(request, reply) 
  return reply("Hello " + World());

module.exports = 
    Hello,

这将使您的代码更具可读性,并且您只会导出您实际需要的内容。此question 对您的问题有其他解决方案。

【讨论】:

您的第二个示例运行良好!很奇怪,第一个例子没有。【参考方案3】:

我们来演示一下this

this 没有定义函数所在的对象。它定义了调用函数的位置。所以虽然;

var obj = 
    Hello : function(request, reply) 
        return reply("Hello " + this.World());
    ,
    World : function() 
        return "World";
    
;
obj.Hello("test", console.log);

会很好用;这不会;

var obj =  Hello : function(request, reply) 
                      return reply("Hello " + this.World());
                    ,
            World : function() 
                      return "World";
                    
          ;

setTimeout(obj.Hello,100,"test",console.log);

这只是因为obj.Hello 将在setTimeOut 函数的定义中分配一个参数,并且该参数将作为window 调用,即该函数的this。所以你应该这样做;

var obj =  Hello : function(request, reply) 
                      return reply("Hello " + this.World());
                    ,
            World : function() 
                      return "World";
                    
          ;

setTimeout(obj.Hello.bind(obj),100,"test",console.log);
//or 
setTimeout(obj.Hello.bind(obj,"test",console.log),100);
//or
setTimeout((x,y) => obj.Hello(x,y),100,"test",console.log);

【讨论】:

这是非常有用的解释,我认为 reply() 函数可能在幕后做了一些“魔术”,这把它搞砸了,但是 Ahmads 的回答(第二部分)工作得很好而且很漂亮几乎完全相同,只是语法不同。我真的对原因感到困惑,但它仍然有效 @Michael 在您的问题下查看我的评论。只要您的testy 模块的Hello 方法中有return reply("Hello " + this.World()); 指令,无论reply 有什么魔法,它都应该可以工作。

以上是关于从模块中调用 Node.js 模块函数的主要内容,如果未能解决你的问题,请参考以下文章

Node.js缓冲模块Buffer

node.js学习笔记之调用函数

node.js模块系统函数

Node.js(window)基础——node环境下的模块,模块间调用

什么 TypeScript 配置产生最接近 Node.js 14 功能的输出?

从 Node.js 中的模块导出函数的语法是啥?