2014-10-17 55 views
0

一些代碼行給你想法我想問什麼。 代碼開始與Ussing setTimeout在一個循環內不允許阻塞

var webSocketsServerPort = 8002; 
var webSocketServer = require('websocket').server; 
var conns = []; 

我使用數組各是conns連接成功後推用戶。我把額外的(他們的ID)信息放在那裏,以便我可以識別用戶。

而當我需要向用戶發送特定信息時,我會調用以下函數。

function sendMessage(userID, message){ 
    for(var i = 0, len = conns.length; i < len; ++i){ 
     if(conns[i].customData.ID == userID){ 
      conns[i].sendUTF(message); 
     } 
    } 
} 


我的問題是: 它是一個更好的主意,如果萬一有setTimeout(function(){conns[i].sendUTF(message)},1)使更換conns[i].sendUTF(message);有5000級連接的用戶sendUTF(msg)將無法​​阻止循環,在最好的情況下,所有的消息將同時發送。

+0

*首先:*當您找到id時跳出循環! *第二:*爲什麼使用循環?改變設計,所以你不需要一個循環! – epascarello 2014-10-17 12:46:11

+0

如何更改設計? – Enve 2014-10-17 12:47:18

+0

將用戶標識作爲關鍵字的對象。 – epascarello 2014-10-17 12:47:35

回答

1

如果你改變你的設計由ID而不是對象的數組安排一切事物,沒有理由要循環查找所有用戶的連接。您只需要遍歷每個用戶的多個連接。

var connections = {}; 
function addConnection (userId, conn) { 
    if (!connections[userId]) { 
     connections[userId] = []; 
    } 
    connections[userId].push(conn); 
} 

var getUserConnections (userId) { 
    return connections[userId]; 
} 
1

這不會幫助你的想法。如果當時不會「阻塞」,它會在1 ms內「阻塞」。

1

setTimeout這種方式只會延遲執行,而不是排隊。 JS仍然會阻塞地運行你的for循環來獲得全部5000個物品進入等待隊列,然後清除其他物品的堆棧。

你需要的是讓每一次迭代。由於您使用的是NodeJS,因此您可以使用process.nextTick()安排下一次迭代。這是一個簡單的例子。

var i = 0; 
var length = cons.length; 

function foo(){ 
    // if not yet the limit, schedule the next 
    if(i++ < length) process.nextTick(foo); 

    // Run as usual 
    if(conns[i].customData.ID == userID) conns[i].sendUTF(message); 

}