2013-09-10 3 views
3

Мой код выглядит следующим образом:Как я могу гарантировать выполнение jQuery Каждое утверждение перед продолжением?

$(".qtyfield").each(function (index) { 
    if (this.value != "" && this.value > 0) { 
     var fieldname = this.id; 
     countme = countme + 1; 
     var tmpProductID = fieldname.split("_") 
     var ProductID = tmpProductID[1]; 
     var ShowPrice = $(this).closest('td').prev('td').text(); 
     var Quantity = this.value; 
     ShowPrice = ShowPrice.replace("$", ""); 
     isItemInCart(ProductID).done(function() { 
      if (isItemInCartVar) { 
       updateQuantityByProductID(ProductID, Quantity); 
      } 
      else { 
       addToCartWithQty(ProductID, ShowPrice, Quantity); 
      } 

     }); 
     this.value = ''; 
    } 
}); 

мне нужно убедиться, что этот блок кода завершается (все Ajax звонки включены) перед выполнением каких-либо дальнейших заявлений.

Пару точек ..

  1. isItemInCart является функцией с Ajax вызовов
  2. updateQuantityByProductID является функцией с помощью AJAX вызова
  3. addToCartWithQty является функцией с помощью AJAX вызова
  4. I не знаю, сколько предметов в каждой коллекции (оно может измениться)

ответ

0

Посмотрите на отложенные jQuery. Каждый $.ajax вызов возвращает «обещание» вы можете ждать, чтобы решить:

var promise1 = $.ajax(...) 
var promise2 = $.ajax(...) 

Затем ждать, чтобы они были решены:

$.when(promise1, promise2).then(function(){ 
    //ready to rumble 
}); 

Как вы сказали, вы не знаете, сколько элементов в каждой коллекции, просто задвиньте обещание в массив, который может быть использован в $.when следующим образом:

var promises = []; 
promises.push($.ajax(...)); 
$.when.apply(this, promises).then(function(){...}); 
+0

Я видел здесь такие вещи довольно немного, но не совсем уверен, что мне нужно сделать, чтобы применить его к моему коду. Вы можете помочь? – TRaymond

+0

Я попробую. кажется, что вы уже используете отложенные, так как 'isItemInCart' используется с 'done()'. теперь вы должны позволить другим функциям (updateQuantityByProductID, addToCartWithQty) вернуть обещание тоже, и направить их все в массив, как упоминалось в моем сообщении. если вам нужна дополнительная помощь, я бы попросил вас включить соответствующие части вашего сайта в jsfiddle? – schellmax

+0

также обратите внимание, что вы должны сделать это только в том случае, если вашей архитектуре приложения действительно необходимо разделить этот процесс на разные функции на стороне клиента - в противном случае я бы рекомендовал использовать одно из других решений, размещенных здесь, обрабатывая все на стороне сервера (и возможно, добавить транзакции db) – schellmax

2

Я бы реорганизовать код так, чтоЦиклявляется серверной. Таким образом, вы можете подготовить массив на клиенте, отправить его с помощью ajax (с уникальным вызовом), а затем распаковать его на сервере, где будет цикл each. Что делать, если ваша петля состоит из миллиардов элементов? Умножьте это на длину заголовка html.

Вместо этого вы можете просто подготовить массив следующим образом.

var serverSide = []; 

$(".qtyfield").each(function (index) { 

    serverSide.push("the data you need"); 

}); 

вы можете затем отправить его в виде строки JSON

var myArg = JSON.stringify(serverSide) 

или запятую (для более простых структур)

var myArg = serverSide.join(','); 

и имеют уникальный АЯКС вызов, который может вернуться любое значение/сообщение об ошибке

$.post("link", myArg).success(function(data){ alert("data"); }) 

Я не знаю, какая у вас поддержка на стороне сервера, но если вы используете PHP, вы можете декодировать строку JSON с помощью json_decode.

Если вы используете C#, вы можете взглянуть на JSON.net.

В любом случае, у вас будет такая гибкость, как эта. Напротив, делая каждый цикл на клиенте IS, это не лучшее решение. У Ajax-вызовов есть заголовки.

2

Моим решением было бы объединить всю эту логику в один звонок, что-то вроде updateCart().

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

[ 
    {productId: 123, quantity: 2, price: 123}, 
    {productId: 456, quantity: 1, price: 200} 
] 

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

Один запрос также уменьшает вероятность конфликта сеансов и улучшает согласованность состояния вашей корзины.

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

+0

действительно, лучше, чем мое решение, используя отложенные. – schellmax

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