2015-06-01 2 views
0

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

Что происходит, если пользователь добавляет элемент (действие 1), я вызываю асинхронный вызов, а затем пользователь меняет количество другого элемента (действие 2), мне бы хотелось, чтобы ответ действия 2 показывал вверх. Поскольку эти вызовы асинхронны, возможно, самый последний ответ, который я получаю, является результатом действия 1, поэтому сумма заказа неверна.

Какой шаблон следует использовать для того, чтобы не запускать один и тот же вызов AJAX до тех пор, пока предыдущий не будет завершен?

Для уточнения:

Запросы AJAX, которые происходят те же самые. Скажем, я делаю это $ .get ('destination_url'). Мне просто нужно убедиться, что я не делаю того же запроса, пока предыдущий не будет выполнен/не выполнен.

+1

Я думаю, что вы можете искать объекты обещания: см. ['.promise()'] (https://api.jquery.com/promise/). Вы можете счесть полезным изучить ['.done()'] (https://api.jquery.com/deferred.done/), ['.fail()'] (https: //api.jquery .com/deferred.fail /) и ['. always()'] (https://api.jquery.com/deferred.always/). – War10ck

+0

Предлагаю вам взглянуть на следующую статью SO. Ответ jAndy - это то, что вы ищете. [Запросы ajax очереди с использованием jQuery.queue()] (http://stackoverflow.com/questions/4785724/queue-ajax-requests-using-jquery-queue) – MightyLampshade

+0

Возможно, вам захочется блокировать другие параметры, когда задачи, связанные с выбранными выполняется, например, показывая счетчик или отключив другие параметры и т. д. – lshettyl

ответ

0

Я полагаю, что вы вызываете последовательные запросы Ajax после done() для текущего запроса Ajax называются:

$.ajax(options).done(function (data) { 
    // your logic 
    $.ajax(newOptions); 
}); 
+0

Я не вижу, как это позволит OP «очереди» на его запросы. Справедливо и хорошо делать новый AJAX в обратном вызове .done(), но он не будет вызывать его последующие запросы, если они выполняются быстро. – MightyLampshade

0

Обновлен:

function AjaxCall1() 
{ 
    return $.ajax({ 
     type: "POST", 
     url: webMethod, 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     data: parameters, 
     success: function (data, st) { 
     } 
} 

$(document).ready(function() { 
    $.when(AjaxCall1()).done(function(){ 
     AjaxCall1(); //call same ajax call again once the first one is called 
    }) 
}); 
+0

Это не помогло бы. Ajax-вызовы одинаковы. Мне просто нужно убедиться, что этого не произойдет, пока не произойдет первое. –

+0

@HommerSmith Я обновил свой ответ. Разве они не срабатывают из двух разных мест? – imGreg

0

jQuery.active возвращает целое число, которое является числом в настоящее время открываются активные запросы ajax.

Таким образом, вы могли бы сделать проверку, прежде чем сделать вызов Ajax,

function checkAndCallAjax() { 
    if(jQuery.active == 0) { doAjax() } 
} 

, а затем добавить и ajaxStop обработчиков для вызова checkAndCallAjax вы можете убедиться, что вы не имеете никаких запросов параллельных заказов. AjaxStop сообщит вам, когда закончится вызов ajax.

0

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

$(function() { 

    $("#actions").on("click", ".update", function() { 
     var $this = $(this); 
     var label = $this.text(); 
     $this.siblings().prop("disabled", true); 
     $this.text("Please wait..."); 
     //Ajax call 
     $.ajax({ 
      method: "POST", // or whatever fits 
      url: "/echo/html/", // your url 
      data: { method: "methodName" } // whatever data 
     }).done(function(data) { 
      //do stuff with returned data 
      //Enable the controls 
      $this.siblings().prop("disabled", false); 
      $this.text(label); 
     }).fail(function() { 
      //Handler error related stuff 
      alert("There was an error!"); 
      //Enable the controls 
      $this.siblings().prop("disabled", false); 
     }); 
    }); 
}); 

HTML Пример:

<div id="actions"> 
    <button class="update add">+1</button> 
    <button class="update subtract">-1</button> 
    <button class="update delete">Delete</button> 
</div> 

=Working Demo=

Надежда, что помогает.

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