首页 > 解决方案 > 在 socket.on 处理程序之外使用数据

问题描述

这可能是一个简单的答案,但我很难弄清楚。我想在 socket.on 之外使用来自这些套接字的数据来比较它们以做某事。我试过使用全局变量但没有运气。我正在考虑对它们进行分组,但“master”是一个 io.emit,而 id 是一个 socket.emit。

var playerId;
var masterId;

// Player socket.id
socket.on('id', function(data){
    console.log(data.id);
    var playerId = data.id;
});

// // Master socket.id
socket.on('master', function(data){
    console.log(data.master + ' is the master');
    var masterId = data.master;
});

if (playerId == masterId){
    // do something
}

标签: javascriptnode.jssocket.io

解决方案


你如何处理这件事有几个问题。

首先是范围问题。虽然全局并没有本质上不正确的地方,playerId并且masterId当您var playerId在函数内部使用playerId时,无论是否具有相同的名称,它都将作用域限定为该函数。例如:

var playerId = 2;

function scoped(data) {
  var playerId = data.id;
  console.log(`${playerId} from the func. scoped`);
}

scoped({
  id: 4
});
console.log(`${playerId} from global scope`);
body {
  margin: 0;
}

.as-console-wrapper {
  height: 100%;
  max-height: initial !important;
}

第二个问题是id并且master都是事件。您的程序不会在何时或是否会触发它们。没什么大不了的,直到您尝试在事件侦听器之后将它们与以下内容进行比较:if ( playerId == masterId ) { .. }。由于 JS 是从上到下执行的,而且 if 语句是在全局范围内的,所以在注册事件监听器后立即执行。这意味着您的 if 语句将始终失败。正如 klanmiko 提到的,您可以编写一个单独的函数来为您进行检查。

这是一个例子。关键区别在于分配给/data.id的全局版本,而不是声明变量的本地版本并在每次分配后调用。playerIdmasterIdcheckId()

var playerId = null;
var masterId = null;

socket.on('id', function(data) {
  playerId = data.id; // Assigns the global playerId = data.id;
  checkId();
});

socket.on('master', function(data) {
  masterId = data.id; // Assigns the global masterId = data.id;
  checkId();
});

function checkId() {
  if ( playerId == masterId ) {
    // Do something cool!
  }
}

推荐阅读