我有点困惑,关于如何在Node.js中要求和使用模块。
我的方案如下:
我在一个文件中编写了一个完整的服务器,它使用Socket.io进行实时通信。
现在index.js变得非常大了,我想将代码分成几个模块,以使其更易于管理。
例如,我有一些功能可以为客户提供调查,并回复他们的答案。我将所有这些函数放在一个单独的模块中,并在index.js中要求它。到目前为止工作正常。
我唯一关心的是,如果有另一种方法在模块中使用SAME套接字实例。
我目前的编码如下:
index.js:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Survey = require('./survey');
io.on('connection', function (client) {
client.on('getCurrentQuestion', function (data) {
Survey.getCurrentQuestion(parseInt(data.survey_id), client.id);
});
});
server.listen(port, server_url, function () {
Survey.init(io);
});
survey.js:
var io = null;
var Survey = {};
Survey.init = function(socketio) {
io = socketio;
};
Survey.getCurrentQuestion = function(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
module.exports = Survey;
这种方式有效,但我很高兴将init函数中的io
传递给所需的模块。
这样做的“正确方法”是什么?
如果我在调查模块中require('socket.io')
,它是否与index.js
中的实例相同?
我怎么会要求,因为它需要server
,这需要app
中创建的index.js
?
我很困惑,希望有人可以帮助我。谢谢!
答案 0 :(得分:1)
导入node.JS库时,您还可以传入对象。在您的情况下,index.js文件应更改为以下内容:
//index.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Survey = require('./survey')(io);
然后只需更改您的survey.js代码即可获取io对象:
//survey.js
module.exports = function (io) {
var Survey = {};
Survey.getCurrentQuestion = function(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
return Survey;
};
要回答您的其他问题:
如果你在调查模块中require('socket.io')
,它将是与index.js不同的实例。
修改的
如果你想要一种更现代的方式...你可以使用ES6格式并创建一个类来更好地做到这一点:
'ES6 index.js
import SurveyClass from './Survey';
import * as express from 'express';
let app = express();
let server = require('http').createServer(app);
let io = require('socket.io')(server);
let MySurveyClass= SurveyClass(io);
let myInstance = new MySurveyClass();
myInstance.getCurrentQuestion(5, "some-socket-id");
'ES6 survey.js
export default class Survey{
constructor(io){
this.io= io;
};
getCurrentQuestion(survey_id, socket_id) {
var response = {
status: "unknown",
survey_id: survey_id
};
// [...] some code that processes everything
// then uses Socket.io to push something back to the client
this.io.sockets.in(socket_id).emit('getCurrentQuestion', response);
};
}
答案 1 :(得分:0)
在多个模块中执行此操作时:
var socketio = require('socket.io');
然后它将是所有要求的相同对象。
但如果你这样做:
var io = require('socket.io')(server);
即使两个地方的server
中都有相同的对象,io
也会是一个不同的值,因为它来自require('socket.io')
返回的函数的不同调用,即使这些功能是一样的。
如果您想确保io
相同,那么您可以做到,例如类似这样的事情:创建一个导出io
承诺的模块以及一些初始化它的方法 - 一个获取server
和所需一切的函数。现在,在您拥有server
的地方,您可以要求模块并使用该导出的函数对其进行初始化,在其他地方您可以导入模块并使用承诺。
而不是承诺你可以使用回调甚至只是导出对象上的一个属性,这个属性最初可能是未定义的,并且在初始化socket.io时被定义但使用promise可能是最简单的解决方案,以确保你和#39;在尚未准备就绪的情况下不再使用它。
在你的问题中你没有提到你是否使用某个框架以及哪个框架(如果有的话),但是像Hapi这样的一些框架为你提供了一种简单的方法来共享这样的功能。例如。见:
如果您使用Hapi,那么您应该使用插件。如果其他框架然后搜索类似的功能。