Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Асинхронный вывод данных из базы MySQL (https://javascript.ru/forum/misc/44056-asinkhronnyjj-vyvod-dannykh-iz-bazy-mysql.html)

Vikky 04.01.2014 15:41

Асинхронный вывод данных из базы MySQL
 
Приветствую!

Уже пару дней бьюсь с этим вопросом, поэтому буду рад любой помощи (и да.. Гугл уже спрашивал).

Делаю простой счётчик кликов по ссылкам, который сохраняет данные в БД и выводит их при перезагрузке страницы (для каждой страницы - свой результат). С сохранением - проблем никаких нет, всё асинхронно. Но когда я пытаюсь так же асинхронно вывести значение - вместо цифр пустота. Причём без ошибок в консоли :blink:

JS код вывода следующий:

function getXmlHttp() {
	var xmlHttp;
	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();
	}
	return xmlHttp;
}

var xmlHttp = getXmlHttp();
var params = "count=" + document.location.href; // берём URL документа для определения кол-ва кликов на данной странице
xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", "counter.php", true);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send(params);
xmlHttp.onreadystatechange = function() {
	if (this.readyState !== 4) return;
	if (this.status !== 200) return;
}
return xmlHttp.responseText;


PHP код вывода следующий:

$showQuery = $db->query("SELECT `counter` FROM `table` WHERE `url`='{$_POST['count']}' LIMIT 1");

if (!empty($_POST['count'])) 
{

	if ($showQuery->num_rows === 0) 
	{
		echo '0';
	} 
	else 
	{
		$counter = $showQuery->fetch_array();		
		echo $counter['counter'];
	}

}


Подскажите, пожалуйста, почему не работает при таком раскладе? При этом, если поменять значение:
xmlHttp.open("POST", "counter.php", false);

то всё выводится нормально, но боюсь при увеличении БД будет наблюдаться "подвисание" страницы, как написано тут..

Vikky 04.01.2014 17:42

Цитата:

Сообщение от Rise (Сообщение 290555)
Строка 28, детка

А что не так-то с ней? Почему точно такой же код, но с другим POST-параметром отправляет "+1" в БД при клике "на ура", а выводить не хочет?

Vikky 04.01.2014 17:49

Цитата:

Сообщение от Rise (Сообщение 290558)
Очевидно потому что этот параметр не для красоты там есть...

Решительно не понимаю о чём идёт речь.. или зайти с этим вопросом позже, когда адекватные жители форума с праздников выйдут? :blink: ОК.

danik.js 04.01.2014 18:00

Vikky, на то она и асинхронность, что твой код не останавливается, дожидаясь ответа, а продолжает выполняться дальше. А это значит что return responseText выполнится тутже, когда запрос даже еще не дошел до сервера!
Решение - используй callback-функции. Схожая тема: http://javascript.ru/forum/jquery/44...osle-post.html

Vikky 04.01.2014 18:31

Цитата:

Сообщение от danik.js (Сообщение 290561)
Vikky, на то она и асинхронность, что твой код не останавливается, дожидаясь ответа, а продолжает выполняться дальше. А это значит что return responseText выполнится тутже, когда запрос даже еще не дошел до сервера!
Решение - используй callback-функции. Схожая тема: http://javascript.ru/forum/jquery/44...osle-post.html

Именно не поняв ничего в том топике - я этот и создал.. :(

Просто не понимаю: как может быть, что
xmlHttp.onreadystatechange = function() {
	if (xmlHttp.readyState !== 4) return;
	
	if (xmlHttp.status === 200) {
		alert(xmlHttp.responseText);
	}
}

выводит значение из БД во всплывающем окошке, а просто на страницу - нет.. :blink:

danik.js 04.01.2014 18:35

Цитата:

Сообщение от Vikky
а просто на страницу

просто - это как? Ну напиши document.write(xmlHttp.responseText) - выведет просто на страницу.

Vikky 04.01.2014 20:34

Цитата:

Сообщение от danik.js (Сообщение 290565)
просто - это как? Ну напиши document.write(xmlHttp.responseText) - выведет просто на страницу.

Просто так, это если всё обёрнуто в функцию и нужно выводить в совершенно другом месте.

JS:
...
function myFunction() {
	var xmlHttp = getXmlHttp();
	var params = "count=" + document.location.href;
	xmlHttp = new XMLHttpRequest();
	xmlHttp.open("POST", "counter.php", true);
	xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xmlHttp.send(params);
	xmlHttp.onreadystatechange = function() {
		if (xmlHttp.readyState !== 4) return;
		if (xmlHttp.status == 200) {
			return xmlHttp.responseText;
		}
	}
}
...
...
...
document.getElementById("myID").innerHTML = myFunction();
...
...


В таком варианте даёт undefined вместо пустой строки.

danik.js 04.01.2014 23:26

Цитата:

Сообщение от Vikky
return xmlHttp.responseText;

Эта конструкция вернет результат в то место, откуда была вызвана функция (это основы программирования). Внимание, вопрос: где происходит вызов этой функции? И соответственно куда улетит возвращаемое значение?

Чтоб ты понимал пример по-проще:

var fn = function() {
    return 'abc';
};


var result = fn(); // тут вызов функции, return вернет значение вот прям в эту строчку, в место вызова функции.

danik.js 04.01.2014 23:40

Упростил твой код:

function myFunction() {
   // тут создаются какие-то объекты, не важно...
}

document.getElementById("myID").innerHTML = myFunction();


Раз функция ничего не возвращает, то откуда чему-то взяться, кроме как undefined?

Vikky 05.01.2014 00:15

Цитата:

Сообщение от danik.js (Сообщение 290588)
Упростил твой код:

function myFunction() {
   // тут создаются какие-то объекты, не важно...
}

document.getElementById("myID").innerHTML = myFunction();


Раз функция ничего не возвращает, то откуда чему-то взяться, кроме как undefined?

Хм.. так как вернуть в моей функции xmlHttp.responseText ? Кроме как вот так - больше никак не получилось..

JS:
...
function myFunction() {
	var xmlHttp = getXmlHttp();
	var params = "count=" + document.location.href;
	xmlHttp = new XMLHttpRequest();
	xmlHttp.open("POST", "counter.php", true);
	xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xmlHttp.send(params);
	xmlHttp.onreadystatechange = function() {
		if (xmlHttp.readyState !== 4) return;
		if (xmlHttp.status == 200) {
			document.getElementById("myID").innerHTML = xmlHttp.responseText;
		}
	}
}

HTML:
<script>
window.onload = function() { 
	myFunction(); // типа того.. не суть, просто с загрузкой страницы запускать функцию
}
</script>

<div id="myID"></div>

При этом всё равно на доли секунды показывается undefined, а уже потом данные из БД..

danik.js 05.01.2014 00:47

Цитата:

Сообщение от Vikky
Хм.. так как вернуть в моей функции xmlHttp.responseText ? Кроме как вот так - больше никак не получилось..

Да, примерно так. А через return никак, потому что xhr запрос происходит асинхронно, то есть он не блокирует поток, а выполняется параллельно, следовательно функция не будет висеть и ждать результата, а значит и вернуть она ничего не может (как она тебе вернет результат из будущего?)
Цитата:

Сообщение от Vikky
При этом всё равно на доли секунды показывается undefined, а уже потом данные из БД..

Дык ты убери сам же присваиваешь undefined (тот что возвращает функция myFunction). Убери присвоение просто.

danik.js 05.01.2014 00:49

Цитата:

Сообщение от Vikky
var xmlHttp = getXmlHttp();

удали строчку, она не нужна. и функцию getXmlHttp удали - она нужна была раньше, когда был актуален IE6-7. Только var не потеряй.

Vikky 05.01.2014 01:26

Цитата:

Сообщение от danik.js (Сообщение 290602)
Дык ты убери сам же присваиваешь undefined (тот что возвращает функция myFunction). Убери присвоение просто.

Так, что ли?

...
function myFunction() {
	...
	xmlHttp.onreadystatechange = function() {
		if (xmlHttp.readyState !== 4) return;
		if (xmlHttp.status == 200) {
			document.getElementById("myID").innerHTML = xmlHttp.responseText;
		}
	}
	return 0;
}


Цитата:

Сообщение от danik.js (Сообщение 290602)
Только var не потеряй.

Что-то типа этого?
var xmlHttp = new XMLHttpRequest();

danik.js 05.01.2014 09:17

Цитата:

Сообщение от danik.js
document.getElementById("myID").innerHTML = myFunction();

Вот эту строчку удали. Оставь из нее только вызов myFunction()
Зачем ты пустоту (результат вызова myFunction() присваиваешь в innerHTML ?) Отсюда и undefined был.

Vikky 05.01.2014 09:43

Цитата:

Сообщение от danik.js (Сообщение 290617)
Вот эту строчку удали. Оставь из нее только вызов myFunction()
Зачем ты пустоту (результат вызова myFunction() присваиваешь в innerHTML ?) Отсюда и undefined был.

Ой, спасибо! Теперь всё по полочкам и понятно :thanks:

p.s. карму, как я понимаю здешние законы, только те кто был уже с рождения JS-профи за подобный топик минусуют? ОК.


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