Node.js数组切片操作是否“线程安全”?

时间:2018-07-11 20:08:21

标签: node.js websocket

我有一个简单的Websocket聊天服务器,可以处理多个客户端。我使用数组来跟踪所有客户端,并在客户端关闭连接时对数组进行切片。

我想知道何时多个客户端大约同时关闭连接,是否会切成阵列导致问题。

这是代码段:

var clients = []; 
var wsServer = new webSocketServer ({
    httpServer: httpserver
});

wsServer.on('request', function(request) {
    var connection = request.accept(null, request.origin);
    var index = clients.push(connection) - 1;

....

connection.on('close', function(connection) {
    for (var i=0; i<clients.length; i++) 
        if (i != index) clients[i].sendUTF('Some client has left the chat!');

    //At this point some other clients may have disconnected and the above 
    //for-loop may be running for another connection.

   clients.splice(index, 1);

   //After the array has been sliced, will the for-loop for other 
   //connection(s) fail?

1 个答案:

答案 0 :(得分:3)

JavaScript是单线程的,所以,Array.splice是线程安全的。

异步回调仅可在调用堆栈为空时进入调用堆栈。因此,如果调用堆栈上有一个Array.splice,则另一个包含Array.splice的回调将不得不等到第一个回调完成。

const arr = [1,2,3,4];
request('http://foo.com', (err, res, body) => {
   arr.splice(0, 1)
});

request('http://bar.com', (err, res, body) => {
   arr.splice(0, 1)
});

考虑上面的代码段。如果这些请求同时完成(为争辩而想象一下)。然后一个回调,foo.combar.com将进入调用堆栈。 全部将执行该回调内的同步代码(将执行异步调用,但不执行该回调),并且直到调用堆栈被处理后,才能处理来自另一个请求的回调空。因此foo.combar.com回调不能同时处理。

JavaScript是单线程的,它具有一个调用堆栈,因此一次只能执行一件事。