【问题标题】:Getting all sockets id from Nodejs socketio array从 Node Js 套接字 io 数组获取所有套接字 id
【发布时间】:2016-05-17 08:39:23
【问题描述】:

我正在使用 socketio 0.9 创建一个复杂的程序,为了存储所有的套接字 id,我使用这样的数组:

var clients = {};

我正在使用我自己的序列号来识别我的套接字并将它们存储在我的数组中,然后我正在设置“套接字”键及其实际值。

clients[serial] = { "socket": socket.id };

现在我需要从我的阵列中获取所有套接字 ID,而不需要其序列号。我该怎么做?

我正在尝试这个迭代,但我不知道如何获取套接字属性:

for(var c in clients) {
c.socket
}

谢谢。

【问题讨论】:

    标签: javascript arrays node.js socket.io


    【解决方案1】:

    这不是 JavaScript 中的数组

    虽然 PHP 将其称为 关联数组,但它在 JavaScript 中只是一个 object(也称为 hash),并且是一个 hash table散列图 在理论计算机科学中。

    在...中使用

    话虽如此,for ... in 指令迭代对象的,而不是其

    var clients = {
      clientid1: { name: "John Doe", age: 42 },
      clientid2: { name: "Jane Doe", age: 34 }
    };
    
    for (var key in clients) {
      console.log(key);
    }
    
    Console output:
      "clientid1"
      "clientid2"
    

    因此,要访问客户端哈希的 ,例如 socket 属性,请像这样迭代它:

    for (var serial in clients) {
      clients[serial].socket.sendSomethingViaTheSocket(...);
    }
    

    好吧,for ... in 似乎可行,为什么还有其他解决方案存在?

    由于 JavaScript 是一种具有 prototypal inheritance 的非常动态的语言,您可以添加、更改和删除几乎每个 JavaScript 对象的属性,并向对象原型添加新的属性和方法(哪些方法和属性的“蓝图”某个“类”的对象具有)。

    这意味着这是完全有效的 JavaScript 代码:

    HTMLElement.prototype.isParagraph = false;
    HTMLParagraphElement.prototype.isParagraph = true;
    
    var myElement = document.querySelector(...);
    if (myElement.isParagraph) {
      // that's possible in javascript!
    }
    

    由于 JavaScript 中的大多数对象都允许扩展原型,因此 Object 原型也是可能的,它是所有非值对象的祖先。假设您想定义自己的方法来向对象添加属性(为什么会决定这样做):

    Object.prototype.addProperty = function (name, value) {
      this[name] = value;
    };
    
    var exampleCustomer = { name: "John Doe" };
    exampleCustomer.addProperty("age", 42);
    console.log(exampleCustomer.age);    // logs 42 on the console
    

    但这意味着从现在开始,JavaScript 中的每个 对象都有一个addProperty 方法,因此当你使用for ... in 时,你不会得到你期望的结果:

    for (var key in exampleCustomer) {
      console.log('key ', key, ' equals ', exampleCustomer[key]);
    }
    
    Console output:
      key name equals John Doe
      key age equals 42
      key addProperty equals function (name, value) { ... }
           ^ oops!
    

    您现在会发现for ... in 还会迭代在您要迭代的对象的原型链上设置的属性。这意味着使用for ... in 很好当且仅当,您可以确定没有人更改您的原型。

    ES5:Object.defineProperty 和 Object.defineProperties

    从 ES5 开始,有两种方法可以缓解这个问题。认识Object.definePropertyObject.defineProperties。如果您需要在原型上定义方法,请使用以下方法:

    Object.defineProperty(
      Object.prototype, // the object the property should be defined on
      "addProperty", // name of the property
      {
        enumerable: false, // should the property show up in for ... in / Object.keys()?
        writable: true, // can the value of this property be changed with obj.addProperty = ..?
        configurable: true, // can this property be changed with another defineProperty call?
        value: function (name, value) { this[name] = value; }
      }
    );
    

    当您使用configurable: false 定义属性时,它不会显示在for ... in 循环中。

    解决原型问题的解决方案(原生 JavaScript)

    如果您不想使用库来解决上述问题,您可以使用原生 JavaScript 中包含的一些方法。

    Object.keysArray.prototype.forEach

    Object.keys(clients).forEach(function (key) {
      clients[key].socket.sendSomething();
    });
    // will NOT iterate over prototype-inherited properties
    

    ECMAScript2015/ECMAScript6 for ... of(适用于 node 4+ 和新浏览器,无 IE)

    for (let clientid of clients) {
      clients[clientid].socket.sendSomething();
    }
    

    // 也不会迭代原型继承的属性

    您还可以在 node 4+ 中使用Array.prototype.map箭头函数 以非常可读的方式获取所有客户端的套接字:

    let clientSockets = Object.keys(clients).map(k => clients[k].socket);
    // clientSockets contains the socket of all clients now
    

    解决原型问题(库)的解决方案

    下划线/lodash:

    _.each(clients, function (client) {
      client.socket.sendSomething();
    });
    

    jQuery:

    $.each(clients, function (id, client) {
      client.socket.something();
    });
    

    AngularJS:

    angular.forEach(clients, function (client, id) { // order is different than with jQuery!
      client.socket.something();
    });
    

    【讨论】:

    • 你的回答太棒了!
    【解决方案2】:

    您可以像这样创建一个包含您保存的所有 socketId 的数组:

    var arr = [];
    Object.keys(clients).forEach(function(s){
        arr.push(clients[s].socket)    
    });
    console.log(arr); // arr would have all socketIds
    

    这里 Object.keys() 返回客户端中所有序列的数组,然后用于迭代并查找您保存的每个 socketId 值

    【讨论】:

      【解决方案3】:

      首先,clients 不是数组而是对象。

      您可以使用Object.keys() 或在lodash 的帮助下获取所有密钥,您可以使用_.keys 或者如果您只对套接字ID 感兴趣:

      let _ = require('lodash');
      
      console.log(_.map(clients, 'socket');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-14
        • 1970-01-01
        • 2014-11-03
        • 2022-09-25
        • 2016-12-13
        • 1970-01-01
        • 1970-01-01
        • 2019-02-20
        相关资源
        最近更新 更多