01.09.2011, 04:15
|
Профессор
|
|
Регистрация: 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 запросов вместо того, чтобы делать новые?
Но тогда почему вариант через кнопку Сохранить проходит на ура?
|
|
01.09.2011, 07:56
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
Куча текста и ничего не понятно, какие данные, что, откуда, для чего как... не понятно... куча букв и ничего не ясно.
|
|
01.09.2011, 08:37
|
Профессор
|
|
Регистрация: 22.09.2010
Сообщений: 217
|
|
ОК, сорри. Вот адрес, уже Бог знает который раз его пишу
http://popov654.pp.ru/livemarks
Логин admin, пароль test
Попробуйте сперва написать что-нибудь в любой чистой ячейке, например в базе Литература, потом кликнуть по бирюзовому квадратику (откроет чистую страницу засчёт выставления оффсета большего, чем кол-во записей в таблице БД), подтвердите сохранение. Пойдёт асинхронный запрос, правда "глупый", через объект Image(). Но успешный.
Потом вернитесь обратно, кликнув по первому квадрату. Вуаля - всё осталось как было, но это только иллюзия, ибо просмотр в phypMyAdmin говорит об обратном. Можете даже туда же, только через другую вкладку зайти, повторно залогинившись. Изменения должны появиться
Что-то где-то кэшируется?..
|
|
01.09.2011, 08:41
|
Профессор
|
|
Регистрация: 22.09.2010
Сообщений: 217
|
|
Блин... Существенная поправочка: фокус со вторым логином на другой вкладке не поможет
Но в phpMyAdmin данные реально обновляются! Я к сожалению не могу дать Вам доступ чтобы показать... Могу скрин разве что выложить
Вот Вы как думаете: теоретически может так быть, что данные остаются старыми только для моего скрипта?.. Ну я не знаю, веб-сервер же видит, к какому скрипту идёт обращение, да и PHP-интерпретатор тоже. Может кто-то из них чего-то сохраняет? Ну например интерпертатор мог каким-то образом старые переменные использовать вероятно... С результатами предыдущих SQL-запросов
Я не вижу другого рационального объяснения...
Последний раз редактировалось popov654, 01.09.2011 в 08:44.
|
|
01.09.2011, 08:48
|
Профессор
|
|
Регистрация: 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.
|
|
01.09.2011, 09:29
|
|
Кандидат Javascript-наук
|
|
Регистрация: 23.05.2009
Сообщений: 100
|
|
чисто предположение, може autocomplete в инпутах виновен?
Когда назад возвращаетесь, подгружаются какие-нибудь данные или станица?
__________________
Обходя грабли ты теряешь драгоценный жизненный опыт!
|
|
01.09.2011, 10:25
|
Профессор
|
|
Регистрация: 22.09.2010
Сообщений: 217
|
|
Блин, я идиот. Вопрос снимается.
У меня просто не успевали отправиться ВСЕ запросы, а поскольку тип работы определялся лишь по одному ученику... Короче, этому ученику периодически "не везло". По логам веб-сервера проверил. Ну а то, что я видел в phpMyAdmin - это как раз и были те 7-10 записей из 19, что сохранились.
Вопрос: а как сделать чтобы гарантированно убедиться, что все запросы выполнены? Только XMLHttpRequest?
|
|
03.09.2011, 01:56
|
Профессор
|
|
Регистрация: 22.09.2010
Сообщений: 217
|
|
Ау...
|
|
03.09.2011, 02:05
|
Профессор
|
|
Регистрация: 22.09.2010
Сообщений: 217
|
|
Обобщу вопрос: вот есть у меня массив запросов. Ну пока это Image и я проверяю свойство complete, которое должно характеризовать завершение загрузки, причём я даже настроил PHP скрипт так, чтобы он реально, обработав запрос, отдавал изображение 1х1 пиксель.
Если у меня будет XMLHttp, то там будет onReadyStateChange...
Вопрос в другом. Вот есть у меня массив этих объектов, и пока все запросы не отправлены полностью, дальнейшее выполнение кода нужно ЗАБЛОКИРОВАТЬ, чтобы браузер не ушёл на другой адрес. Поскольку обычный setTimeout(), как здесь уже обсуждалось, не останавливает поток выполнения, я использую логическую переменную. Но получается глупо: как только один запрос отправится, она устанавливается в true. Если есть ещё хотя бы один незавершённый запрос, его "прослушиватель", повешенный на setInterval(), конечно перепишет переменную на false...
Но во-первых, он может тупо не успеть, и функция, повешенная на другой таймер и ожидающая разрешения на переход, может сработать. Это первая проблема.
А вторая проблема видимо в том, что я криворукий - у меня после реализации вышеописанного вообще запросы перестали отправляться
Где я слажал?
|
|
03.09.2011, 02:08
|
Профессор
|
|
Регистрация: 22.09.2010
Сообщений: 217
|
|
Есть ещё мысль повесить на setInterval полный обход массива... Но мне это кажется каким-то страшно нерациональным. Ведь если большая часть запросов давно отправлена, мы будем гулять по массиву зря (следовательно, потеря производительности, т.к. запросов может быть до тучи).
Заводить ещё один массив для хранения индексов успешно отправленных - тоже вроде как глупо, по понятным причинам...
|
|
|
|