Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Область видимости переменной (https://javascript.ru/forum/misc/57006-oblast-vidimosti-peremennojj.html)

Lemme 15.07.2015 06:50

Область видимости переменной
 
Почему не записывает данные в переменную data в success?
Внутри этой функции все ок, но
SomeClass.prototype.foo = function(id){
	var data = false;
	ajax({
		method: 'POST',
		url: 'test.php',
		params: 'id='+id,
		success: function(response){
			data = response; // ответ получен
		}
	});
	return data;
}

пробовал и так:
var data = function(response){
		return response;
	}
	ajax({
		method: 'POST',
		url: 'test.php',
		params: 'id='+id,
		success: data
	});
	return data();


Но это работает

function foo(obj){
			obj.test('Hello, World');
		}
		function bar(){
			var data;
			foo({
				test: function(response){
					data = response;
				}
			})
			return data;
		}
		console.log(bar()); //hello world


Извиняюсь, спойлера не нашел, поэтому скидываю (на всякий случай) обертку для Ajax.
function ajax(setting){
	setting.method = setting.method === undefined ? 'GET' : setting.method;
	setting.params = setting.params === undefined ? null : setting.params;

	if (setting.url === undefined || typeof setting.success !== 'function' || (setting.method === 'POST' && setting.params === null)) return false;

	var xmlhttp,
		send = setting.method === 'GET' ? null : setting.params,
		url = setting.method === 'GET' ? setting.url + setting.params : setting.url;
	try{
		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e){
		try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
			xmlhttp = false;
		}
	}
	if (!xmlhttp && typeof XMLHttpRequest !== 'undefined'){
		xmlhttp = new XMLHttpRequest();
	}
	xmlhttp.open(setting.method, url, true);
	if (setting.method === 'POST'){
		xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
	}
	xmlhttp.onreadystatechange = function(){
		if (xmlhttp.readyState == 4){
			if (xmlhttp.status == 200){
				setting.success(xmlhttp.responseText);
			}
		}
	}
	xmlhttp.send(send);
}

Вопрос возможно банальный, но...

Safort 15.07.2015 07:30

Цитата:

Почему не записывает данные в переменную data в success?
Внутри этой функции все ок, но
Потому что это асинхронная операция, а не последовательная. Прочитай по подробнее про AJAX или воспользуйся поиском по форуму, тут такой вопрос постоянно задают.

Lemme 15.07.2015 07:43

Safort, спасибо, запомнил;)

Но, как я понял, синхронный запрос не рекомендуется использовать, как быть? Возможно есть какие-то обходы?

Erolast 15.07.2015 13:29

Lemme, не обращай на него внимания, это местный цепной тролль)

С асинхронными функциями в JS работают с помощью коллбеков (система замыканий тут очень в тему):
SomeClass.prototype.foo = function(id, onSuccess) {
    ajax({
        method: 'POST',
        url: 'test.php',
        params: 'id='+id,
        success: onSuccess
    });
}

var instance = new SomeClass();
instance.foo(10, function(response) {
    console.log(response);
});


Если хочешь упрощения кода - посмотри в сторону Promise из ES6 (это новейшая спецификация языка, только месяц назад релизнулась), с ними код будет выглядить так:
SomeClass.prototype.foo = function(id) {
    return ajax({
        method: 'POST',
        url: 'test.php',
        params: 'id=' + id,
        success: onSuccess
    });
}

var instance = new SomeClass();
instance.foo(10).then(function(response) {
    
});

Промайзы доступны во всех последних браузерах, кроме IE, для него придется подключить какой-нибудь полифилл.

Makarov 15.07.2015 14:03

Добавлю к ответу Erolast что релизация промисов есть в том же jQuery

Lemme 15.07.2015 14:19

Erolast, спасибо, буду разбираться с этим. А насчет этого тролля.... Я ему уже все сказал=)
Makarov, да мне это не для реального проекта, а для обучения. Соответственно, не использую никаких библиотек/фреймворков.

Erolast 15.07.2015 14:36

Раз обучаешься - тогда и в остальные фичи ES6 углубись, там очень много вкусного, в том числе и высокоуровневый синтаксис объявления классов.

Lemme 15.07.2015 14:51

Erolast, ага, я уже читал о ES6, но не думал, что данная спецификация уже используется.

Erolast 15.07.2015 15:02

ES6 используется уже как несколько лет, сейчас просто утвердился стандарт.

Lemme 15.07.2015 15:20

Erolast, я в js начал углубляться совсем недавно, поэтому для меня все в новинку. Раньше использовал. jQuery и то по мелочам=)


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