2014-09-09 3 views
0

В настоящее время я работаю над программным обеспечением для отслеживания времени . Я развиваюсь в grails, но этот вопрос связан исключительно с javascript и асинхронными запросами.AJAX - Несколько одновременных запросов: Задержка выполнения AJAX до завершения определенных вызовов

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

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

Теперь к моей проблеме: может быть много запросов AJAX. Пользователи пациентов могут только нажать кнопку «создать активность» только один раз и подождать, пока она не будет создана. Другие, однако, могут просто нажимать, пока что-то не произойдет.

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

У меня есть updateTemplate(data, day) функцию, которая вызывается OnSuccess соответствующих вызовов Ajax в одном из моих функций saveRecord(), deleteRecord(), pasteRecords(), makeEditable() (отменить сохранение). Вот пример АЯКС вызова в JQuery:

$.ajax({ 
    type: "POST", 
    url: "${g.createLink(controller:"controller", action:"action")}", 
    data: requestJson, 
    contentType:"application/json; charset=utf-8", 
    async: true, 
    success: function(data, textstatus) {updateTemplate(data["template"], tag); updateTable(data["table"]);}, 
}); 

В действии контроллера, объект JSON, визуализируется как ответ, содержащий ключи template и table. Каждый ключ имеет шаблон, выделенный как назначенный ему String, используя g.render.

Теперь, когда я нажимаю на create несколько раз в очень коротких интервалах, из-за асинхронных вызовов некоторые действия create (или другие) выполняются одновременно. Дело в том, что updateTemplate просто отображает данные из ответа; данные для рендеринга собираются в действии контроллера create. Но «последнее» действие запроса только находит созданные сами объекты. Я думаю, что это потому, что create действия выполняются одновременно

Я полагаю, что есть что-то я либо усложнять или делать что-то по существу неправильно работает со страницей, которая refreshs динамически. Единственное, что я обнаружил, что это помогает, - это синхронные вызовы, которые работают, но пользовательский интерфейс был ужасен. Какие варианты я должен сделать для этой работы? Неужели это или я просто искал неправильный подход? Как я могу сделать это более надежным, чтобы нетерпеливые пользователи не смогли сломать мой код?

********* EDIT: ********

Я знаю, что я мог бы блокировать кнопки или сочетания клавиш, использовать синхронные вызовы или подобные вещи, чтобы избежать тех, вопросы. Тем не менее, я хочу знать, можно ли разрешить его с несколькими запросами AJAX. Таким образом, пользователь должен иметь возможность добавлять новые действия, хотя они не появятся сразу.В любом случае, есть прядильщик для обратной связи. Я просто хочу как-то убедиться, что перед запуском «последнего» запроса AJAX, база данных обновлена, так что действие контроллера будет отвечать обновленным шаблоном gsp с нулевыми объектами.

+0

Как насчет блокировки кнопки до тех пор, пока у вас не будет ответа (+ показ любого предустановителя)? Я не понимаю, что вы хотите сказать в других частях, что не так с вашим кодом ... – hffmr

+0

Привет, спасибо за ваш ответ. Это хорошая идея, но вы также можете использовать ярлыки. Я просто вообще задаюсь вопросом, является ли это плохим подходом к обновлению представления или его можно улучшить. Половина инструмента существует в устаревшем коде, и я пытаюсь сделать эту работу без перезапуска с нуля с подходящей инфраструктурой javascript. Я в основном сейчас, что не так, я просто не вижу ничего о том, как обрабатывать многие одновременные вызовы AJAX. – nst1nctz

+0

Вы также можете блокировать ярлыки ... Я предполагаю, что вы вызываете нажатие кнопки и по сокращению одной функции, и в этой функции вы можете добавить какое-то условие, которое проверяет, есть ли выполняемый вызов или нет (установите 'running = true' перед вызовом и onSuccess 'running = false', вот и все) – hffmr

ответ

0

С помощью this Stackoverflow answer я нашел способ гарантировать, что вызов ajax - в функции javascript выполняется последним - всегда отвечает современной моделью. В принципе, я добавляю javascript-функции, содержащие вызовы AJAX в очереди ожидания, если «критический» запрос AJAX был инициирован до этого, но еще не завершен.

Для этого я определяю функцию doCallAjaxBusyAwareFunction(callable), которая проверяет, является ли глобальная переменная Global.busy «истинным» перед выполнением функции callable. Если это правда, функция будет выполнена снова, пока Global.busy не будет false, чтобы, наконец, выполнить функцию - сбор данных из DOM - и запустить запрос AJAX.

Определение глобальной переменной:

var Global = { 
    ajaxIsBusy = false//, 
    //additional Global scope variables 
}; 

Определение функции doCallAjaxBusyAwareFunction:

function doCallAjaxBusyAwareFunction(callable) { 
     if(Global.busy == true){ 
      console.log("Global.busy = " + Global.busy + ". Timout set! Try again in 100ms!!"); 
      setTimeout(function(){doCallAjaxBusyAwareFunction(callable);}, 100); 
     }  
     else{     
      console.log("Global.busy = " + Global.busy + ". Call function!!"); 
      callable();    
     } 
    } 

Чтобы пометить функцию, содержащую Аякса как критическое, я пусть это установить Global.busy = true с самого начала и Global.busy = false на AJAX завершена. Пример вызова:

function xyz(){ 
    Global.busy = true; 
    //collect ajax request parameters from DOM 

    $.ajax({ 
     //desired ajax settings 
     complete: function(data, status){ Global.busy = false; } 
    } 

Поскольку Global.busy установлен на истинное значение в самом начале, DOM, не может манипулировать - например, по delete с, а функция xyz собирает данные DOM. Но когда функция была выполнена, все равно Global.busy === true до завершения вызова ajax.

сгореть Аякс вызов из функции «занят осведомленнома»:

doCallAjaxBusyAwareFunction(function(){ 
    //collect DOM data 

    $.ajax({/*AJAX settings*/}); 
}); 

.... или сгореть АЯКС вызов из функции «занято-курса», который также отмечен критическим сам (в основном то, что В основном я использую его для:

doCallAjaxBusyAwareFunction(function(){ 
    Global.busy = true; 
    //collect DOM data 

    $.ajax({ 
     //AJAX SETTINGS 
     complete: function(data, status){ Global.busy = false; } 
    }); 
}); 

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

Смежные вопросы