2017-02-22 26 views
-1

У меня есть код, который использует node.js и socket.io.Неопределенная переменная вне функции

Когда я написал этот код таким образом;

стороне сервера:

function display(width, height){ 
 
    this.width = width * 2; 
 
    this.height = height * 2; 
 
} 
 

 
function position(x, y){ 
 
    this.x = x; 
 
    this.y = y; 
 
} 
 

 
function initialize(){ 
 
    for(var x = circlePosition.length; x < circleCount; x++){ 
 
    circlePosition[x] = new position(Math.random() * (resolution.width - (-resolution.width)) + (-resolution.width), Math.random() * (resolution.height - (-resolution.height)) + (-resolution.height)); 
 
    
 
    } 
 
} 
 

 
socket.on('display', 
 
     function(data) { 
 
     resolution = new display(data.width, data.height); 
 
     initialize(); 
 
     io.sockets.emit('positioning', circlePosition); 
 
     });

на стороне клиента;

var position; 
 
var resolution = { 
 
\t \t width: 1366, 
 
\t \t height: 666 
 
\t }; 
 

 
\t socket.emit('display', resolution); 
 

 
\t socket.on('positioning', 
 
\t \t function(data){ 
 
\t \t \t position = data; 
 
\t \t }); 
 
\t console.log(position); // <---

Переменная положение не определено, но если я использовать этот код на стороне клиента

var position; 
 
var resolution = { 
 
\t \t width: 1366, 
 
\t \t height: 666 
 
\t }; 
 

 
\t socket.emit('display', resolution); 
 

 
\t socket.on('positioning', 
 
\t \t function(data){ 
 
\t \t \t position = data; 
 
     console.log(position); // <--- 
 
\t \t }); 
 
\t

Он имеет значение. Почему я не могу использовать значение, отправленное с помощью функции socket.io вне функции?

+0

Вы видите журнал данных? –

+0

@MuhammadAli да, сначала набор кода был не определен, на втором наборе он имеет свое значение. – Rich

+0

oh жаль, что я не заметил ваш второй последний фрагмент –

ответ

1

Подумайте о том, что именно эта строка кода делает:

socket.on('positioning', 
    function(data){ 
     position = data; 
    }); 

Это настройка функции обратного вызова , которая будет вызываться, когда вы получите событие positioning. Но учтите, что эта функция еще не вызывается! Он будет называться когда-нибудь в будущем. Это всего лишь инициализации функции.

Если вы поставите console.log() вызов после инициализации функции обратного вызова, которая будет происходить console.log()перед тем функция на самом деле называется! Вот почему переменная не определена, потому что переменная еще не установлена!

Если поставить console.log() вызов внутри функции обратного вызова, то вы гарантировать, что это произойдет после того, как функция обратного вызова вызывается, поэтому переменная установлена.

Это может быть более ясным, если вы не используете встроенную функцию:

var position; 
var resolution = { 
     width: 1366, 
     height: 666 
    }; 

socket.emit('display', resolution); 
socket.on('positioning', myCallback); 
console.log(position); 

function myCallback(data){ 
    position = data; 
} 

Это именно то, что ваш код делает, только теперь я использую именованную функцию вместо встроенной функции. Но теперь более очевидно, что обратный вызов еще не вызывается, когда выполняется console.log().

+0

Итак, в основном я должен поставить console.log внутри функции, чтобы читать инициирование? – Rich

+0

@JoshuaAlzate Да. Я только что отредактировал свой ответ, чтобы включить другой пример, который может сделать его более очевидным. –

+0

спасибо человеку. Ты замечательный! – Rich

1

В первом сценарии клиента ваш console.log(position) работает до того, как ваш обработчик событий запущен. Помните, что когда вы делаете socket.on(...), вы просто регистрируете обработчик событий, который может быть вызван в будущем. Остальная часть вашего кода продолжает работать. Итак, следующая строка после регистрации вашего обработчика событий - это оператор console.log(). Поскольку обработчик событий еще не был запущен (он зарегистрирован, но пока ничего не произошло, чтобы его запустить), position еще не имеет значения.

Так, глядя на ваш код:

socket.on('positioning', function(data) { 
    position = data; 
}); 
// position has not yet been set because the above event handler 
// has not yet been triggered 
console.log(position); 

единственное безопасное место, чтобы использовать данные, отправленные positioning события ВНУТРИ обратного вызова, который является именно то, что вы делаете в другом сценарии, где работают вещи правильно:

socket.on('positioning', function(data) { 
    // use the data here 
    console.log(data); 
}); 

FYI, это фундаментальная концепция программирования, управляемой событиями. Вы регистрируете обработчики событий, которые в будущем называются. Вы часто не знаете, когда они будут вызваны, поэтому вам нужно просто обрабатывать данные, которые они предоставляют внутри обработчика событий, когда они вызываются.

+0

Как? но я написал присвоение значения до того, как я написал console.log. – Rich

+0

@JoshuaAlzate. Нет. Все, что вы сделали, это зарегистрировать обработчик событий, который будет называться когда-нибудь в будущем. Код в этой функции еще не запущен. Это основа программирования, управляемого событиями, как работает node.js. – jfriend00

+0

Так что в основном я должен поставить console.log внутри функции, чтобы иметь возможность прочитать инициирование? – Rich

0

socket.on() это асинхронно называют - это означает, что ваш будет вызывать только анонимную функцию послеdata был полностью загружен с сервера.


Примечания: Вы можете использовать position из другого кода, который вне анонимной функции после анонимной функции была запущена (Да, вы должны ждать, чтобы получить доступ к нему). Но как?Ну, лучший способ сделать это, чтобы положить зависимый код в свою собственную функцию, а затем вызвать эту функцию из функции обратного вызова, как в этом примере:

var position; 
 
var resolution = { 
 
    width: 1366, 
 
    height: 666 
 
}; 
 

 
socket.emit('display', resolution); 
 

 
socket.on('positioning', 
 
    function(data) { 
 
    loadPosition(); // <--- 
 
    } 
 
); 
 

 
function loadPosition() { 
 
    position = data; 
 
    console.log(position); // ... do whatever you need to do with postion here 
 
}

+0

Почему вы положили мне отрицательный знак ??? – Teocci

+0

Я не тот, кто дал эту отрицательную оценку. – Rich

+0

mhm кто-то пытается получить значки, вероятно. – Teocci

0

Вы можете передать вы возражаете/значение, полученное от ответа CallBack

var position; 
var resolution = { 
    width: 1366, 
    height: 666 
}; 

socket.emit('display', resolution); 

socket.on('positioning', 
    function(data){ 
     position = data; 
    positionUpdate() 
    }); 

function positionUpdate(){ 
console.log(position); 
} 
+0

почему отрицательная отметка –

+0

Я не дал отрицательный знак, я собираюсь попробовать это хорошо, я думаю, он выглядит великолепно. – Rich

+0

Я думаю, его другой человек, отрицающий –

0

если вы еще не решили свою проблему, попробуйте это. Это то, что я сделал.

var resolution = { 
    width: 1366, 
    height: 666 
}; 

socket.emit('display', resolution); 

socket.on('positioning', function(data){ 
    getPosition(data, position); 
}); 

var getPosition = function(data, callback){ 
    callback(data); 
} 

var position = function(data){ 
    console.log(data); // <-- 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^