Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 03.09.2011, 02:12
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

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

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

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

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

Я убрал лишний текст (сорри за повтор). Код приводить вряд ли есть смысл: там ровно то, что написано выше, только ещё менее наглядно (например, потому что логических флага зачем-то сделано два).

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

Вот код функции посылки запросов:
function saveChanges() {
   var imgs = new Array();
   for (var i = 0; i < queries.length; i++) {
      imgs.push(new Image())
      imgs[i].src = queries[i]
   }
   var tries = 0;
   var timer = setInterval(function() {
      tries++
      requestComplete = true
      for (var i = 0; i < imgs.length; i++) {
         if (!imgs[i].complete) {
            requestComplete = false
         }
      }
      if (requestComplete) {
         clearInterval(timer);
         alert('Данные сохранены! Запросов выполнено: ' + queries.length)
         queries = []
      } else if (tries > 8) {
         clearInterval(timer);
      }
   }, 100);
   return false;
}

var requestComplete = false



А вот код, который выполняет ожидание перед сменой блока:

elem.onclick = function() {
      if (queries.length && confirm('Вы хотите сохранить введённые данные?')) {
         saveChanges()
         var tries = 0;
         var timer = setInterval(function() {
            tries++
            if (requestComplete) {
               requestComplete = false
               clearInterval(timer)
               document.form1.action = 'edit.php'
               document.form1.from.value = pages * 25
               document.form1.submit()
            }
            if (tries > 10) {
               clearInterval(timer)
               alert('Ошибка запроса')
            }
         }, 200);
      } else {
         document.form1.action = 'edit.php'
         document.form1.from.value = pages * 25
         document.form1.submit()
      }
   }


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

Я отредактировал неудачные на мой взгляд места, это исправленная версия. Однако на длинных запросах (29 записей сразу например) почему-то вылетает алерт с неудачной отправкой (при одиночных запросах всё ОК).

Добавлено спустя 5 минут:

Всё! Работает! Я всего лишь увеличил таймауты, и этого оказалось достаточно. Вот итоговый код:

function saveChanges() {
   var imgs = new Array();
   for (var i = 0; i < queries.length; i++) {
      imgs.push(new Image())
      imgs[i].src = queries[i]
   }
   var tries = 0;
   var timer = setInterval(function() {
      tries++
      requestComplete = true
      for (var i = 0; i < imgs.length; i++) {
         if (!imgs[i].complete) {
            requestComplete = false
         }
      }
      if (requestComplete) {
         clearInterval(timer);
         alert('Данные сохранены! Запросов выполнено: ' + queries.length)
         queries = []
      } else if (tries > 8) {
         clearInterval(timer);
      }
   }, 500);
   return false;
}

var requestComplete = false


elem.onclick = function() {
      if (queries.length && confirm('Вы хотите сохранить введённые данные?')) {
         saveChanges()
         var tries = 0;
         var timer = setInterval(function() {
            tries++
            if (requestComplete) {
               requestComplete = false
               clearInterval(timer)
               document.form1.action = 'edit.php'
               document.form1.from.value = pages * 25
               document.form1.submit()
            }
            if (tries > 3) {
               clearInterval(timer)
               alert('Ошибка запроса')
            }
         }, 4000);
      } else {
         document.form1.action = 'edit.php'
         document.form1.from.value = pages * 25
         document.form1.submit()
      }
   }

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

Чёрт... Рано обрадовался. Два столбца по 29 запросов уже не тянет. А должна тянуть максимум 25 таких столбцов!

Самое обидное, что пока я не ввёл эти проверки, запросы шли быстрее раз так в пять.

Так и знал, что линейный обход - ужасный способ. И что мне теперь делать? Может, ничего не проверяя, поставить таймаут побольше (секунд 10)? Но тогда ждать юзеру придётся даже при маленьких модификациях базы, даже когда запрос всего один
Ответить с цитированием
  #15 (permalink)  
Старый 03.09.2011, 12:00
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

вы проверяете завершенность по интервалу - ай ай ай.
function saveChanges(callback) {
    var imgs = new Array(), i = 0, max = queries.length - 1;
    
    var timer = setInterval(function(){
        imgs.push(new Image);
        
         // обработчик загрузки для последней картинки
        if (i === max) imgs[i].onload = callback( imgs );
        
        imgs[i].src = queries[i];

        if( ++i > max ) clearInterval(timer);
        
    }, 100);
}


elem.onclick = function() {
    // для экономии места повторяющиеся операции занёс в функцию
    function normForm() {
        var a = document.form1;
        a.action = 'edit.php';
        a.from.value = pages * 25
        a.submit();
    };
    
    if (queries.length && confirm('Вы хотите сохранить введённые данные ? ')) {
        
        saveChanges(/*выполнится по завершении запроса*/function(a) {
            
            // a - массив картинок.
            alert('Данные сохранены! Запросов выполнено : '+a.length);
            queries = [];
            normForm();
        });

    } else {
        normForm();
    }
}

Последний раз редактировалось melky, 03.09.2011 в 12:03.
Ответить с цитированием
  #16 (permalink)  
Старый 04.09.2011, 16:24
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Спасибо) Не сообразил, что onload есть не только у body
Туплю)

P.S. Там код этого обработчика несколько сложнее (потому что при нажатии на разные кнопки вызываются разные блоки), но я допилю, всё ОК
Ответить с цитированием
  #17 (permalink)  
Старый 04.09.2011, 16:25
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Жаль, плюсик Вам в карму не отправить
Ответить с цитированием
  #18 (permalink)  
Старый 04.09.2011, 19:39
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Да ёлки-палки...
После такой переделки у меня теперь та же ситуация, что была в самом начале: пишется, но не всё.

Я изучил лог-файл сервера. В большинстве случаев не хватает одного запроса, иногда один запрос отправляется на адрес undefined. Странно...
Ответить с цитированием
  #19 (permalink)  
Старый 04.09.2011, 19:46
Профессор
Отправить личное сообщение для popov654 Посмотреть профиль Найти все сообщения от popov654
 
Регистрация: 22.09.2010
Сообщений: 217

Ну я так и думал. Надо было поменять эти две строки местами:

if (i == max) imgs[i].onload = callback( imgs );
imgs[i].src = queries[i];


Походу до присваивания src интерпретатор считал рисунок загруженным (как раз по адресу undefined), и запускался callback, очищающий весь массив адресов запроса. В итоге запрос либо не уходил вовсе, либо уходил на адрес undefined.

Настораживает ещё вот какой факт: иногда помимо запроса undefined не хватало ещё одного запроса. Поэтому вопрос к Вам: Вы уверены, что все предыдущие запросы успеют дойти? Обработчик-то мы привязали только к последнему
Ответить с цитированием
  #20 (permalink)  
Старый 04.09.2011, 20:29
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

как они могут не дойти? картинки создаются в цикле - значит запросы так же создаются в цикле. посмотрите вкладку Network в инструменте веб-мастера
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Странное поведение 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