Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 01.09.2011, 04:15
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Очень странное поведение
Только что закончил отладку нового механизма сохранения данных в БД. Столкнулся с ужасной вещью, причины которой мне совсем не понятны.

В общем есть страница с таблицей для ввода данных, наверху есть трекер для переключания между блоками данных, внизу есть кнопка Сохранить, на неё повешен обработчик. Обработчик выполняет сохранение лишь тех полей, в которых побывал фокус (хранится всё это счастье в специальном массиве в виде строк запроса к PHP-скрипту). При клике по какому-либо квадратику трекера сценарий выводит confirm с вопросом о том, нужно ли сохранить данные перед переходом.

Открыл параллельно в разных вкладках браузера свою систему и phpMyAdmin (для 100% проверки, глюк проявлялся и без этого).

Кстати, после confirm-а появляется alert с сообщением о количестве выполненных запросов. Так вот, к делу.

Происходит ужасная вещь: если нажать на кнопки ОК в confirm и alert довольно быстро (в пределах 3-х секунд), то внешне всё пройдёт гладко. Более того, данные в базе перепишутся (phpMyAdmin тому подтверждение). После этого случится запланированный редирект. Но вот после клика на изначальной кнопке трекера - по сути, это возврат к прежнему блоку, который реализован через отправку формы на тот же адрес в качестве action, используя скрытое поле, в котором хранится сдвиг для чтения из БД (как и первый переход, они равносильны) - произойдёт переход к прежнему блоку, но данные там будут... СТАРЫЕ!

Я до сих пор не могу понять чё это за фигня. Самое интересное, что если перед подтверждением confirm-а выждать секунд 5-7, то баг не проявляется. Если пользоваться кнопкой сохранения снизу, а уж потом делать переход к другому блоку используя трекер, ничего подобного тоже нет. И самое главное, в IE7 я этого тоже не заметил.

По логике вещей, такого быть не должно.

P.S. Только что проверил, в Opera ситуация ещё того печальней. Даже длительное ожидание не помогает И в IE7 теперь кстати то же самое... Может, баги PHP-интерпретатора, который использует результаты старых MySQL запросов вместо того, чтобы делать новые?
Но тогда почему вариант через кнопку Сохранить проходит на ура?
Ответить с цитированием
  #2 (permalink)  
Старый 01.09.2011, 07:56
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Куча текста и ничего не понятно, какие данные, что, откуда, для чего как... не понятно... куча букв и ничего не ясно.
Ответить с цитированием
  #3 (permalink)  
Старый 01.09.2011, 08:37
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

ОК, сорри. Вот адрес, уже Бог знает который раз его пишу

http://popov654.pp.ru/livemarks

Логин admin, пароль test

Попробуйте сперва написать что-нибудь в любой чистой ячейке, например в базе Литература, потом кликнуть по бирюзовому квадратику (откроет чистую страницу засчёт выставления оффсета большего, чем кол-во записей в таблице БД), подтвердите сохранение. Пойдёт асинхронный запрос, правда "глупый", через объект Image(). Но успешный.
Потом вернитесь обратно, кликнув по первому квадрату. Вуаля - всё осталось как было, но это только иллюзия, ибо просмотр в phypMyAdmin говорит об обратном. Можете даже туда же, только через другую вкладку зайти, повторно залогинившись. Изменения должны появиться

Что-то где-то кэшируется?..
Ответить с цитированием
  #4 (permalink)  
Старый 01.09.2011, 08:41
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Блин... Существенная поправочка: фокус со вторым логином на другой вкладке не поможет

Но в phpMyAdmin данные реально обновляются! Я к сожалению не могу дать Вам доступ чтобы показать... Могу скрин разве что выложить

Вот Вы как думаете: теоретически может так быть, что данные остаются старыми только для моего скрипта?.. Ну я не знаю, веб-сервер же видит, к какому скрипту идёт обращение, да и PHP-интерпретатор тоже. Может кто-то из них чего-то сохраняет? Ну например интерпертатор мог каким-то образом старые переменные использовать вероятно... С результатами предыдущих SQL-запросов
Я не вижу другого рационального объяснения...

Последний раз редактировалось popov654, 01.09.2011 в 08:44.
Ответить с цитированием
  #5 (permalink)  
Старый 01.09.2011, 08:48
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Ну кажется начало что-то прорисовывается. При варианте, когда я сохраняю через кнопку снизу, Опера например секунд 6-7 чего-то "грузит" даже после алерта, хотя алерт идёт по коду уже после назначения нужных URL картинкам. Вот код:

function saveChanges() {
   var imgs = new Array();
   for (var i = 0; i < queries.length; i++) {
      imgs.push(new Image())
      imgs[i].src = queries[i]
   }
   setTimeout('queries = []', 100)
   alert('Данные сохранены! Выполнено запросов: ' + queries.length)
   return false;
}


Возможно, запросы-то и уходят гораздо раньше, но для браузера этот таймаут важен, чтобы поменять статус готовности документа и запомнить состояние полей формы. А если, не дождавшись этого, перенаправить его скриптом куда-нибудь, то почему-то при возврате он отображает не то, что есть на самом деле.

Последний раз редактировалось popov654, 01.09.2011 в 08:51.
Ответить с цитированием
  #6 (permalink)  
Старый 01.09.2011, 09:29
Аватар для Geddar
Кандидат Javascript-наук
Отправить личное сообщение для Geddar Посмотреть профиль Найти все сообщения от Geddar
 
Регистрация: 23.05.2009
Сообщений: 100

чисто предположение, може autocomplete в инпутах виновен?
Когда назад возвращаетесь, подгружаются какие-нибудь данные или станица?
__________________
Обходя грабли ты теряешь драгоценный жизненный опыт!
Ответить с цитированием
  #7 (permalink)  
Старый 01.09.2011, 10:25
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Блин, я идиот. Вопрос снимается.
У меня просто не успевали отправиться ВСЕ запросы, а поскольку тип работы определялся лишь по одному ученику... Короче, этому ученику периодически "не везло". По логам веб-сервера проверил. Ну а то, что я видел в phpMyAdmin - это как раз и были те 7-10 записей из 19, что сохранились.

Вопрос: а как сделать чтобы гарантированно убедиться, что все запросы выполнены? Только XMLHttpRequest?
Ответить с цитированием
  #8 (permalink)  
Старый 03.09.2011, 01:56
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Ау...
Ответить с цитированием
  #9 (permalink)  
Старый 03.09.2011, 02:05
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Обобщу вопрос: вот есть у меня массив запросов. Ну пока это Image и я проверяю свойство complete, которое должно характеризовать завершение загрузки, причём я даже настроил PHP скрипт так, чтобы он реально, обработав запрос, отдавал изображение 1х1 пиксель.

Если у меня будет XMLHttp, то там будет onReadyStateChange...

Вопрос в другом. Вот есть у меня массив этих объектов, и пока все запросы не отправлены полностью, дальнейшее выполнение кода нужно ЗАБЛОКИРОВАТЬ, чтобы браузер не ушёл на другой адрес. Поскольку обычный setTimeout(), как здесь уже обсуждалось, не останавливает поток выполнения, я использую логическую переменную. Но получается глупо: как только один запрос отправится, она устанавливается в true. Если есть ещё хотя бы один незавершённый запрос, его "прослушиватель", повешенный на setInterval(), конечно перепишет переменную на false...

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

А вторая проблема видимо в том, что я криворукий - у меня после реализации вышеописанного вообще запросы перестали отправляться

Где я слажал?
Ответить с цитированием
  #10 (permalink)  
Старый 03.09.2011, 02:08
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Есть ещё мысль повесить на setInterval полный обход массива... Но мне это кажется каким-то страшно нерациональным. Ведь если большая часть запросов давно отправлена, мы будем гулять по массиву зря (следовательно, потеря производительности, т.к. запросов может быть до тучи).
Заводить ещё один массив для хранения индексов успешно отправленных - тоже вроде как глупо, по понятным причинам...
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Странное поведение Dojo. Kuzya59 Dojo toolkit 4 15.10.2011 15:42
Странное поведение... popov654 Общие вопросы Javascript 6 29.03.2011 05:14
Странное поведение переменной mycoding Серверные языки и технологии 4 14.01.2011 19:18
DragAndDrop у гридов в плавающих окнах странное поведение PavelK ExtJS 0 29.07.2010 15:26
Странное поведение replace cooli0 Общие вопросы Javascript 4 25.01.2010 17:16