LINUX.ORG.RU

Предотвратить повторные запросы

 ,


1

3

Как принято это делать?

Допустим у меня есть функция через которую проходят все запросы. Что-то вроде:

function serverRequest (url, data, func) {
    document.State.numConnection = document.State.numConnection+1
    WUI.indicationRequest()
    $.post(url, data, function(data) {
            document.State.numConnection = document.State.numConnection-1
            WUI.indicationRequest()
            func(data)
	})
}
Как правильно отследить, что такой-то запрос уже выполняется (допустим пользователь тычит в кнопку без перерыва и генерится куча ненужных запросов) и просто сборосить его.

Кажется логичным пихать куда нибудь некоторый хэш от параметров serverRequest в начале запроса и удалять по завершению. А как это сделать максимально просто и быстро? Может есть какое-то стандартное решение?

★★★★★

Ответ на: комментарий от Apple-ch

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

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от anonymous

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

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Deleted

Целиком что-ли? Слишком расточительно. Надо какой-то хэш сгенерить, причем не сложный и быстрый.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от ritsufag

Я не совсем понял как его можно использовать тут. Но я вообще не уверен, что все правильно про него понял (только что дочитал на хабре). Однако это все равно интересно и с этим стоит разобраться. Спасибо.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

У тебя нет параметров запроса, что там такое запрашивается? Что-то мне подсказывает, что ты что-то недорассказал.

Deleted
()
Ответ на: комментарий от Suntechnic

Можно создать обещание и пока запрос не выполнен не разрешать делать новый. Хотя я знаком с ними по ангулар и не помню чем они отличаются.
Но это все костыли конечно, лучше таки извернуться и блокировать кнопку.

ritsufag ★★★★★
()

http://lodash.com/docs#debounce и http://lodash.com/docs#throttle

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

Хотя можно объект JSON-ом перегонять в строку и использовать как уникальный ключ. md5 считать нет смысла - памяти сэкономите копейки, и будет лишняя (не нужная) операция.

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

Vit ★★★★★
()
var app = app || {};

// http://www.yuiblog.com/blog/2007/06/12/module-pattern/
app.serverRequest = (function($) {
    var xhr = false;

    var numConnection = 0;

    var serverRequest = function(url, data, func) {
        if (xhr !== false) // если ajax-запрос выполняется в данный момент, то не выполнять новый
            return false;
        numConnection = numConnection+1
        WUI.indicationRequest()
        xhr = $.post(url, data, function(data) {
            numConnection = numConnection-1
            WUI.indicationRequest()
            func(data)
            xhr = false;
      })
    }

    var getNumConnection = function() {
        return numConnection;
    }

    return {
        send: serverRequest,
        getNumConnection: getNumConnection
    }
}(jQuery));

app.serverRequest.send(url, data, func);
Black_Roland ★★★★
()
Последнее исправление: Black_Roland (всего исправлений: 1)
Ответ на: комментарий от Deleted

Причем тут параметры запроса? Параметры могут быть одинаковые, но например url'ы разные. А еще могут быть разными только func хотя это уже денормализация и такого по идее быть не должно...

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Black_Roland

Ну в таком случае я мог бы и numConnection проверять на отличность от нуля. Это остановит все запросы если какой-то один уже выполняется. А так нельзя ибо запросы могут быть разные.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от ritsufag

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

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Vit

Что значит «пытаться разделить»? У меня просто есть обертка для post которая обеспечивает пока лишь индикацию выполнения запросов, как можно догадаться по именам функций.

можно объект JSON-ом перегонять в строку и использовать как уникальный ключ

Пока запрос не выполнен, никакого JSON еще нет. Ну и кроме того, вероятно что некоторые запросы будут возвращать не JSON, а готовый HTML. Хотя такого пока нет, но исключать нельзя.

А прерывать повторные запросы необходимо. Допустим имеем свернутые комменты под сообщением и пользователь жмет кнопку развернуть (довольно типичная задача) пять раз подряд. Нафиг нам пять запросов?

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

Возвращай этот xhr и в обработчике кнопки проверяй его состояние.

Black_Roland ★★★★
()
Ответ на: комментарий от Suntechnic

Пока запрос не выполнен, никакого JSON еще нет.

Когда запрос выполнится, это уже будет не запрос а ответ. Еще раз - до xhr сериализуйте запрос джейсоном и используйте в качестве ключа. В качестве значения - xhr, чтобы можно было прервать. После выполнения ключ удаляйте.

Vit ★★★★★
()
Ответ на: комментарий от Weres

Ну да, я примерно так и предполагал сделать. Просто хотел как-то минимизировать длину «ключа».

Suntechnic ★★★★★
() автор топика

Сформировать ключ/хэш/уникальную сигнатуру и в шедуллер?

Дизейбл заманчиво, только как среагировать когда связь пропадет временно, а потом появится? Надо тогда делать отмену/отзыв запроса еще и проверку оффлайн/онлайн ;)

swwwfactory ★★
()
Последнее исправление: swwwfactory (всего исправлений: 2)
Ответ на: комментарий от Weres

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

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от swwwfactory

Сформировать ключ/хэш/уникальную сигнатуру

Да в этом-то и вопрос. Как это сделать быстрее и проще.

Suntechnic ★★★★★
() автор топика

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

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

Я думал и о таком. Но хотелось бы сосредоточить этот функционал в одном месте. Единственная общая точка для всех запросов как раз функция отправки.

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

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

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

Так в чём вопрос? Всё остальное - костыли, которые потом нарожают проблем.

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

Я хочу рассмотреть все варианты ;)

Именно этот мне кажется слишком м... денормализованным что ли.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от Suntechnic

Ну право ваше, но мне интересно, есть ли объективные причины кроме нежелания переписывать существующий код?

ya-betmen ★★★★★
()

ЕМНИП я просто поставил ограничение в 30 секунд на выполнение ajax и в случае повторного запроса выводил сообщение «подождите, не так быстро». Правда проект так и не был запущен, так что не уверен что это хороший подход.

abs ★★★
()
Ответ на: комментарий от ya-betmen

Я же написал - чисто эстетские. Никакого нежелаения переписывать код нет и подавно - там всего пока две разновидности элементов отправляют 3 разновидности запросов.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Есть еще нюанс - один из типов элементов имеет событие сразу прошитое в onclick там что-то вроде «WUI.getThisDataById(15); return false;» - это мне делать гораздо проще. Я понимаю что id можно сунуть куда-то в атрибуты div а событие повесть на класс, но это усложнение которое тут не надо и вот это уже препятствие в отношении снимать/возвращать событие. Либо же ненужные телодвижения по навешиванию событий и извлечении id уже в них. Смысл в том чтобы сделать систему максимально легковесной.

Suntechnic ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

Так в чём вопрос? Всё остальное - костыли, которые потом нарожают проблем.

Да - ты прав, а я нет. Пришлось думать и после обдумывания пришел к выводу что всё так. Не стану обобщать (не думал над общим случаем), но в моем случае действительно надо блочить элемент - запрос обрабатывать ненужно и вредно.

Suntechnic ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.