случайное дублирование запросов ajax

Я заметил, что иногда (случайным образом) мой запрос Mootools ajax отправляется дважды. Второй запрос выполняется сразу же, а первый просто продолжает ждать бесконечно. Я не уверен, что это ошибка в Mootools или что-то, что я сделал.

Это было проверено с помощью firebug в firefox и консоли разработчика в chrome. В IE проверить не удалось, но симптомы те же.

Мне действительно удалось сделать снимок экрана с firebug, показывающий проблему: http://janipeltoniemi.net/ajax.png

Справа вы видите сценарий цикла запроса, который я написал для тестирования. Он просто делает запрос с новым идентификатором после завершения предыдущего запроса, так что ничего особенного в этом нет. Последние две строки в консоли демонстрируют мою проблему. Как видите, у них обоих одинаковый ответ и одинаковый идентификатор. Хеш md5 генерируется с использованием md5(microtime(1)), поэтому он должен быть другим, если эти два запроса на самом деле были разными с одним и тем же идентификатором.

Цикл останавливается в этой точке, потому что он не запускает событие onSuccess, когда завершается последнее. Я предполагаю, что он запустит его, когда другой запрос будет завершен, но этого еще не произошло.

Есть идеи, что здесь происходит?

Чуть не забыл, использую Mootools 1.2.4

Код на картинке:

r = new Request.HTML();
counter = 0;
//increments the counter and requests hello.php
go = function() {
  counter += 1;
  //The loop was too fast and producted some side effects when delay was not used
  r.get.delay( 10, r, [ 'templates/hello.php', { counter: counter } ] )
}
//Create an endless loop. When the request from go() is finished, call go()
r.addEvent( 'success', go );
//Start the endless loop
go();

person jpeltoniemi    schedule 19.07.2010    source источник
comment
это не показывает, какое событие запускает сам запрос ajax.   -  person Dimitar Christoff    schedule 20.07.2010
comment
Я не уверен, что понимаю. Проблема никоим образом не связана с приведенным выше кодом. Это просто быстрый способ воспроизвести проблему и весь необходимый код (кроме ядра Mootools 1.2.4). Я думаю, что проблема здесь в том, чтобы правильно передать сообщение из-за моего плохого английского, поэтому позвольте мне попробовать еще раз: код должен работать как есть в firebug. Он запускает бесконечный цикл с другим запросом, выполняемым по завершении предыдущего. В какой-то момент запрос дублируется (проверьте изображение) и onSuccess не запускается, поэтому цикл останавливается. См. Комментарии в коде для получения дополнительной информации.   -  person jpeltoniemi    schedule 20.07.2010


Ответы (1)


похоже, это связано с переработкой старого экземпляра класса Request до того, как он «готов», поэтому старый запрос запускает onSuccess без сервера, закрывая соединение, когда клиент теряет интерес, и перезапускает его, оставляя firebug в состоянии ожидания.

http://www.jsfiddle.net/dimitar/NF2jz/201/

var r = new Request.HTML({
    url: '/ajax_html_echo/',
    data: {'html': "hello"},
    method: 'post',
    update: 'target_div',
    onSuccess: function(response) {
        (function() {
            go(); // you can reproduce the bug by removing the delay wrap
        }).delay(1000);
    }
});

var counter = 0;

var go = function() {
    counter++;
    // despite of trying r.cancel(), it does not cancel, 
    // you can set onCancel to test this;
    r.cancel().setOptions({
        data: {html: "attempt " + counter}
    }).send();

};

go();

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

я бы сделал что-то вроде этого (но, вероятно, отредактировал, чтобы его можно было отменить):

var counter = 0;
(function go() {
    counter++;
    // fresh instance after success / complete:
    new Request.HTML({
        url: '/ajax_html_echo/',
        data: {'html': "hello " + counter},
        method: 'post',
        update: 'target_div',
        onSuccess: function(response) {
            go();
        }
    }).send();
})();

http://www.jsfiddle.net/dimitar/NF2jz/202/ демонстрации последний код, работает нормально и дополняет друг друга и не мешает друг другу.

person Dimitar Christoff    schedule 20.07.2010
comment
Кажется, я не упомянул, что в исходном случае экземпляр запроса не перерабатывается, извините за это. Кроме того, это не единичный случай. Я замечал это странное поведение кое-где уже некоторое время, но только недавно я начал рассматривать это как проблему. - person jpeltoniemi; 20.07.2010
comment
хорошо - рискуя показаться раздраженным - для справки в будущем опубликуйте свой точный код / ​​URL или создайте тестовый пример, который успешно воспроизводит вашу проблему для всеобщего обозрения. в противном случае вы просто зря тратите время. удачи с исправлением, с классом Request, о котором я знаю, проблем нет. ищите повторяющиеся связанные события, которые вызовут ajax. - person Dimitar Christoff; 20.07.2010
comment
Да, я знаю. Мне, вероятно, следовало опубликовать исходный код, но он действительно не отличается от тестового примера (кроме повторного использования экземпляра запроса), если вы разделите его до костей. Опубликованный код был использован мной, чтобы быстро воспроизвести проблему (иногда требуется ›1000 запросов до появления), и, поскольку он, казалось, успешно воспроизвел проблему, я не думал больше. - person jpeltoniemi; 21.07.2010
comment
Тем не менее, я уверен, что в исходном случае нет никакого вмешательства в запрос, по крайней мере, по моему коду. Сначала создается экземпляр запроса, а сразу после этого отправляется запрос. За исключением onSuccess, который устанавливает только URL-адрес элемента изображения из ответа, экземпляр запроса больше нигде не используется. - person jpeltoniemi; 21.07.2010
comment
когда я говорю тестовый пример, я имею в виду перейти к jsfiddle или mooshell и создать его, аналогично jsfiddle. net / dimitar / NF2jz / 202 и покажите нам, как он ломается (а этот - нет). используйте data: {html: ""}, чтобы смоделировать желаемый ответ и посмотреть, как у вас дела. - person Dimitar Christoff; 21.07.2010
comment
Забавно, я думал, что уже опубликовал комментарий по поводу jsfiddle. В любом случае, я попытался запустить ваш код в jsfiddle, но один запрос занял около 2 секунд, так что это не очень помогает, поскольку мои собственные локальные тесты могут легко занять более 1000 циклов, чтобы вызвать ошибку. Я использовал ваш код для создания автономного тестового скрипта, который должен очень быстро запускаться на локальном сервере. Вы можете увидеть это на gist.github.com/484409. Я не мог заставить его сломаться на chrome this время, но FF заклинило после 3000 циклов или около того. - person jpeltoniemi; 21.07.2010
comment
jsfiddle делает задержку специально, чтобы имитировать сетевое отставание. Что касается сути, замените onSuccess на onComplete или добавьте onFailure для обработки нечетного тайм-аута / проблемы на стороне клиента. - person Dimitar Christoff; 21.07.2010
comment
Я добавил onFailure и onSuccess в суть (gist.github.com/484409). Похоже, что ни одно из событий не срабатывает после появления проблемы. Я собираюсь выполнить тестовый запуск сценария на простаивающем компьютере, чтобы узнать, действительно ли он связан с браузером или ОС. Результаты выложу завтра, когда вернусь к работе. - person jpeltoniemi; 21.07.2010
comment
Хорошо, я провел тесты на другом компьютере за ночь, и они работали нормально. Возможно, мне следовало попробовать это раньше, но поскольку основной причиной начала устранения неполадок было неправильное поведение, о котором сообщил мой клиент, я просто предположил, что проблема не только в моем firefox. Мне нужно разобраться в этом подробнее, но я думаю, что сейчас это моя собственная проблема. Несмотря на то, что проблема остается нерешенной, я приму ваш ответ. Спасибо за содержательный совет :) - person jpeltoniemi; 22.07.2010
comment
Я никогда не использую onSuccess и всегда onComplete - это более надежно. - person Dimitar Christoff; 22.07.2010