Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 24.02.2014, 21:22
Интересующийся
Отправить личное сообщение для vas88811 Посмотреть профиль Найти все сообщения от vas88811
 
Регистрация: 20.12.2013
Сообщений: 22

Отправить, когда четко соберется массив
Подскажите пожалуйста, как решить проблему.. Вообщем есть массив, в котором 50 чисел. Я передаю раз секунду по очереди каждое число другой функции, где полученное число умножается на два и добавляется в массив, который потом отправляется в базу. Так вот проблема в том, что мне нужно, чтобы массив отправлялся в базу четко, когда все 50 чисел обработались и добавились в массив. А мой код отправляет в базу далеко не каждый раз. Очень буду признателен за помощь...


<html>
<head>
type="text/javascript"></script>
<script type="text/javascript" charset="cp1251" >


var mas1 = [];
function vMassiv(x){
var num = x*2;
mas1.push(num);
if(mas1.length == 50){
$.post("vbazu.php", { mas1: mas1}, function(data) { } );
}
}



var mas50; // здесь 50 чисел

count = 0;
function next() {
vMassiv(mas50[count]);
count +=1;
setTimeout(next, 1000);
}
next();


</script>
</head>
<body>
</body>
</html>
Ответить с цитированием
  #2 (permalink)  
Старый 24.02.2014, 22:11
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Сообщение от vas88811
А мой код отправляет в базу далеко не каждый раз
Судя по коду после набора 50 элементов (через 50сек примерно) должна произойти отправка. Не вижу ошибок.
А вот далее массив разрастается до бесконечности, пока наконец не займет всю свободную память и браузер не обрушится.
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #3 (permalink)  
Старый 25.02.2014, 04:55
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

В критические дни нельзя проверять строго:

if(mas1.length == 50){

надо мягко

if(mas1.length >= 50){

и сразу полегчает.
Ответить с цитированием
  #4 (permalink)  
Старый 25.02.2014, 10:45
Интересующийся
Отправить личное сообщение для vas88811 Посмотреть профиль Найти все сообщения от vas88811
 
Регистрация: 20.12.2013
Сообщений: 22

Но почему-то по аналогии с этим кодом, код с вконтакте API у меня не всегда срабатывает. Вот этот код. Он с интервалом в 334 мс посылает функции getMutual друга из массива по очереди. И в этой функции получает друзей каждого друга и высчитывает сколько из них из города '2'. И заносит в массив. И также, когда оба массива >= count_friends, должна происходить отправка в базу. По загрузке если смотреть, вроде бы друзей всех перебирает, но отправка в базу не всегда срабатывает, хотя количество в массивах уже давно нужное..


<html>
<head>

</head>
<body>
<script src="js/jquery-1.8.3.min.js" charset="windows-1251"></script>
<script src="http://vkontakte.ru/js/api/xd_connection.js?2" type="text/javascript"></script>
<script type="text/javascript" charset="cp1251" >
window.onload = (function() {
VK.init(function() {
VK.api("users.get", {user_ids:count,fields:"first_name"}, function(data) {
var friends_data = data.response;
var count_friends = data.response.length;

var ids = [];
var city_count = [];

function getMutual(friendid){

VK.api("friends.get",{user_id:friendid,fields:"cit y"},function(data) {

if (data.response) {

var sum = 0;
for (var i=0;i<data.response.length;i++) if(data.response[i].city == 2) sum++;

ids.push(friendid);
city_count.push(sum);


if (ids.length >= count_friends && city_count.length >= count_friends)
{
$.post(vbazy, { res:ids, res2:city_count}, function(data) {
alert("Занесли");
});
}

}
});
}

count=0;
function next() {
getMutual(friends_data[count].uid);
count +=1;
setTimeout(next, 334);
}
next();
});
});
});


</script>

</body>
</html>
Ответить с цитированием
  #5 (permalink)  
Старый 25.02.2014, 14:40
Интересующийся
Отправить личное сообщение для vas88811 Посмотреть профиль Найти все сообщения от vas88811
 
Регистрация: 20.12.2013
Сообщений: 22

Может быть тут как-то можно использовать $.when ?
Только я пока не могу додуматься, как..
Ответить с цитированием
  #6 (permalink)  
Старый 26.02.2014, 08:17
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Машинально следует останавливать сбор инфы на время записи собранной. Чтобы не думать об интерференции тайаута и аякса. И после отправки инициализировать массив.

где-то var ht = null; // хендл таймаута

ниже

ht=setTimeout(next, 334);

в вбазе

clearTimeout(ht);

в респонзе

array=[];

и вызов функци "ниже"
Ответить с цитированием
  #7 (permalink)  
Старый 26.02.2014, 08:21
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Чтобы понять надо ответить на вопрос:

что произойдет если массив соберется быстрее чем придет ответ сервера об успешной записи предыдущей пачки?

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

Кроме того сам сбор инфы это разве не запросы на сервер через апи?
Ответить с цитированием
  #8 (permalink)  
Старый 26.02.2014, 08:59
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Корявенько, но принип должен быть понятен:

// friends_data came from somewhere
var count_friends=50;
var interval=334;
var th=null;
var ids=[]
var city_count=[];

function getMutual() {

	if(!friends_data.length) { // end of, but unsaved data will be lost
		if(th)
			clearTimeout(th);
		return false; 
	}
	
	friend=friends_data.shift(); // get first elem and reduce array
	friendid=friend.uid;
	var ts = new Date().getTime(); // time start

	VK.api("friends.get",{user_id:friendid,fields:"city"},function(data) {

		if (data.response) {

			var sum = 0;
			for (var i=0;i<data.response.length;i++) 
				if(data.response[i].city == 2) 
					sum++;

			ids.push(friendid);
			city_count.push(sum);

			if (ids.length >= count_friends && city_count.length >= count_friends){
				if(th)
					clearTimeout(th);
				$.post(vbazy, { res:ids, res2:city_count}, function(data) {
					ids=[];
					city_count=[];
					th = setTimeout(getMutual, interval);
					console.log("Занесли");
				});
			}
			else {
				var tn = new Date().getTime();
				var td = interval+ts-tn;
				if(td<0)
					td=1;
				th = setTimeout(getMutual, td); // set remaining time to next call
			}

		}
	});

}

getMutual();

Последний раз редактировалось kostyanet, 26.02.2014 в 09:02.
Ответить с цитированием
  #9 (permalink)  
Старый 26.02.2014, 08:59
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Я понял почему листинги трудно воспринимать на этом форуме - потому что они в зебре. Предлагаю выкосить.
Ответить с цитированием
  #10 (permalink)  
Старый 26.02.2014, 09:08
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

А, понял, вот сюда еще надо проверку на пустой массив воткнуть

if (friends_data.length < 1 || (ids.length >= count_friends && city_count.length >= count_friends)){

чтобы не выделять кусок сохранения в функцию и не потерять несохраненный хвост.
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сформировать массив данных и отправить его в PHP средствами JS westnord Общие вопросы Javascript 21 16.07.2013 12:18
Отправить массив через get на сервер sonntagausgang Общие вопросы Javascript 2 25.05.2013 23:39
Как создать многомерный массив FRIE Общие вопросы Javascript 29 02.06.2010 19:14