Отправить, когда четко соберется массив
Подскажите пожалуйста, как решить проблему.. Вообщем есть массив, в котором 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> |
Цитата:
А вот далее массив разрастается до бесконечности, пока наконец не займет всю свободную память и браузер не обрушится. |
В критические дни нельзя проверять строго:
if(mas1.length == 50){ надо мягко if(mas1.length >= 50){ и сразу полегчает. |
Но почему-то по аналогии с этим кодом, код с вконтакте 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> |
Может быть тут как-то можно использовать $.when ?
Только я пока не могу додуматься, как.. |
Машинально следует останавливать сбор инфы на время записи собранной. Чтобы не думать об интерференции тайаута и аякса. И после отправки инициализировать массив.
где-то var ht = null; // хендл таймаута ниже ht=setTimeout(next, 334); в вбазе clearTimeout(ht); в респонзе array=[]; и вызов функци "ниже" |
Чтобы понять надо ответить на вопрос:
что произойдет если массив соберется быстрее чем придет ответ сервера об успешной записи предыдущей пачки? теоретически пойдет еще один запрос и все отложенные функции выполняться в будущем. Но лично мне приятнее думать что в этот отрезок времени ничего не происходит, чем пытаться подумать о том, что может происходить с учетом чудовищной разницы между скоростью выполнения скрипта в клиенте и ответом сервера, каким бы быстрым он не был. Кроме того сам сбор инфы это разве не запросы на сервер через апи? |
Корявенько, но принип должен быть понятен:
// 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(); |
Я понял почему листинги трудно воспринимать на этом форуме - потому что они в зебре. Предлагаю выкосить.
|
А, понял, вот сюда еще надо проверку на пустой массив воткнуть
if (friends_data.length < 1 || (ids.length >= count_friends && city_count.length >= count_friends)){ чтобы не выделять кусок сохранения в функцию и не потерять несохраненный хвост. |
Часовой пояс GMT +3, время: 08:44. |