2016-10-07 21 views
1

我正在使用node.js,expresssocket.io設置websocket應用程序的基礎。我決定將設置socket.io的代碼放在一個單獨的模塊中將是優雅的,因此我的server.js文件可能更小,請撥打require設置socket.io設置職責。變量作用域(module.exports + socket.io設置)

// server.js 

// set up ====================================================================== 
var express = require('express'); 
var app  = express(); 
var server = require('http').Server(app); 
var io  = require('socket.io')(server); 
var port = process.env.PORT || 80; 

// routes ====================================================================== 
app.get('/', function (req, res) { 
    res.sendFile(__dirname + '/index.html'); 
}); 

// socket.io controller ======================================================== 
require('./app/ws-controller.js')(io); 

// launch ====================================================================== 
server.listen(port, function() { 
    console.log('Server listening on port ' + port + '!'); 
}); 

在我ws-controller.js文件我把一些代碼開始socket.io試驗。

// app/ws-controller.js 
module.exports = function(io) { 
    var numClients = 0; 
    io.on('connection', function (socket) { 
     numClients++; 
     console.log(numClients); 
    }); 
} 

嵌入在index.html中的客戶端腳本很少。

// client side script 
var port = 80; 
var socket = io.connect('http://127.0.0.1:' + port); 

現在到了這一點。在打開指向localhost的新瀏覽器選項卡後,服務器將登錄到控制檯,數量增加numClients。那實際上是如何工作的?我確信numClients會超出範圍,並且預計會在控制檯上看到異常。當綁定到on connection事件的回調函數觸發時,它不應該看到numClients變量,因爲它不是全局的,也不是私有的io對象,對不對?這裏發生了什麼?

回答

1

你必須閱讀更多關於JavaScript中的閉包。在這個特定的例子中,當您啓動應用程序時,numClients = 0;被初始化並保留在匿名function(io)的執行上下文中的內存中。然後,每次有新的連接時,io.on('connection')事件被觸發,回調被執行,numClients仍然在執行上下文中,這就是爲什麼你會看到這個var增加。

+0

因此,當'io.on('connection')'事件被觸發時,回調仍然在'function(io)'的上下文中執行?我認爲這將是一個新鮮的,因爲設置功能創建,執行和遺忘(至少這是我推理)。 – Apo

+1

@Apo節點模塊並非如此。當你需要一個模塊時,節點將緩存模塊,這樣如果另一個文件需要模塊,它將返回相同的實例。這將是有益的:http://stackoverflow.com/questions/9210542/node-js-require-cache-possible-to-invalidate –

+0

閱讀更多的關閉它會幫助你清除懷疑。 JavaScript是如此強大和富有表現力的功能之一。 – Nivesh