Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Область видимости переменных на примере ajax (https://javascript.ru/forum/misc/2871-oblast-vidimosti-peremennykh-na-primere-ajax.html)

human 19.02.2009 19:47

Область видимости переменных на примере ajax
 
Вот не могу понять почему так и как это сделать правильно!!!

у нас есть объект
function Ajax(url){
var _t = this;
this.text = "hello";
this.path = "http://localhost/popup/";
this.url = this.path+url;
HTTP = this.GetAJAXLoader();
HTTP.onreadystatechange = function() {
if (HTTP.readyState==4){
		if (HTTP.status == 200){
			alert("0 => "+this.text); // пытаемся получить значение, получаем undefined и в IE и в FF, это и правильно ведь он пытается лезть в объект HTTP а там свойства text нету
			alert("1 => "+_t.text); // пытаемся получить значение предварительно определив ссылку на объект Ajax, получаем 'hello' в IE и в FF
			_t.text = "edit"; // пытаемся переопределить
			alert("2 => "+_t.text); // вроде бы переопределили
		}
	}
}

HTTP.open("GET",this.url,true);
HTTP.send(null);
alert("3 => "+this.text); // попытка вывести измененную переменную, в результате получим в FF значение 'hello' в IE 'edit'
}



Ajax.prototype.GetAJAXLoader = function(){
	var r={};
   	if (typeof(window.XMLHttpRequest)!='undefined') { 
		try { r = new XMLHttpRequest(); } 
			catch (e) { alert("Ошибка при получении AJAX загрузчика"); } 
		}
   	else if (typeof(window.ActiveXObject)!='undefined') {
       	try { r = new ActiveXObject('Msxml2.XMLHTTP');} 
			catch (e){
				try { r = new ActiveXObject('Microsoft.XMLHTTP'); } 
					catch (e) {alert("Ошибка при получении AJAX загрузчика"); }
			}
	}
	else alert("Браузер не поддерживает AJAX");
	return r;
}


в результате у нас получилось добраться до переменно text только в IE.

Идем дальше и теперь пробуем вот так дважды в конце кода вывести свойство text:

function Ajax(url){
var _t = this;
this.text = "hello";
this.path = "http://localhost/popup/";
this.url = this.path+url;
HTTP = this.GetAJAXLoader();
HTTP.onreadystatechange = function() {
if (HTTP.readyState==4){
		if (HTTP.status == 200){
			alert("0 => "+this.text); // пытаемся получить значение, получаем undefined и в IE и в FF, это и правильно ведь он пытается лезть в объект HTTP а там свойства text нету
			alert("1 => "+_t.text); // пытаемся получить значение предварительно определив ссылку на объект Ajax, получаем 'hello' в IE и в FF
			_t.text = "edit"; // пытаемся переопределить
			alert("2 => "+_t.text); // вроде бы переопределили
		}
	}
}

HTTP.open("GET",this.url,true);
HTTP.send(null);
alert("3 => "+this.text); // попытка вывести измененную переменную, в результате получим в FF значение 'hello' в IE 'edit'
alert("4 => "+this.text);
}

и вуаля в 3 случае IE выведет 'edit' FF 'hello'
а в 4 случае и FF и IE выведут 'edit';

Могу предположить что это происходит из за какого то промежутка времени(а именно из за того что метод вызывается асинхронно), ведь метод onreadystatechange вызывается несколько раз, после вызова метода send().

Так вот мне интересно как же все таки это можно избежать, идея в том чтобы объект Ajax использовать только для получения ответа от сервера, а потом уже в зависимости от ситуации добавлять его в определенный блок.

примерно вот так:
var a = new Ajax('./edit.php');
insertText(a.text,'conteiner');


вот в таком духе....
Может у меня просто зимний тупняк =)) но буду очень признателен за разъяснение ситуации.

Андрей Параничев 19.02.2009 20:04

Для начала советую вам почитать статью про XMLHTTPRequest.

Запросы к серверу, через XMLHTTPRequest - асинхронные, т.е. после начала отправки запроса код продолжает выполняться, следовательно, вывод алерта может произойти до получения ответа с сервера.

Кроме того, у вас неправильный порядок запроса: сначала нужно делать open(), затем устанавливать onreadystatechange и потом вызывать send().

human 19.02.2009 22:34

ну я насамом деле так и подозревал =))

если вы читали пост внимательно =))
Могу предположить что это происходит из за какого то промежутка времени(а именно из за того что метод вызывается асинхронно),

Просто было интересно так ли это, и почему все же IE успевает получить ответ а FF нет

Андрей Параничев 19.02.2009 22:39

human,
То, что IE успел получить ответ - дело случая, в большей мере.

human 19.02.2009 23:12

Ладно всеравно, спасибо =))

Что то ми затупил =))


Часовой пояс GMT +3, время: 12:32.