简体   繁体   中英

How do I guarantee execution of jQuery Each statement before continuing on?

My code is as follows:

$(".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 = '';
    }
});

I need to ensure that this code block completes (all ajax calls included) prior to running any further statements.

A couple of points..

  1. isItemInCart is a function with an Ajax Call
  2. updateQuantityByProductID is a function with an ajax call
  3. addToCartWithQty is a function with an ajax call
  4. I don't know how many items are in the each collection (it could change)

I'd refactor the code so that the each loop is server side. This way you can prepare the array on the client, send it with ajax (with a unique call) and then unpack it on the server where you'll have the each loop. What if your each loop is of billions of elements? Multiply that by the length of an html header.

Instead, you could just prepare the array like this.

var serverSide = [];

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

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

});

you could then send it up as a JSON string

var myArg = JSON.stringify(serverSide)

or a comma separated list (for simpler structures)

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

and have a unique ajax call which can return any value/error message

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

I don't know which server side support you have but if you're using PHP you may decode the JSON string with json_decode .

If you're using C#, you may want to have a look at JSON.net .

Either way, you'll have much more flexibility like this. On the contrary, while doing an each loop on the client IS possible it is not the best solution. Ajax calls have headers.

My solution would be to consolidate all this logic in a single call, something like updateCart() .

On the client side you would create a list of products that need to be updated, eg

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

This data gets sent to the server side where the session data will get updated with the new quantities. Basically, the code on the server side will perform the same logic as you have in all your individual calls, but it will be much faster because there's only a single request.

A single request also reduces the likelihood of session lock contention and improves the consistency of your cart state.

On the client side, there's the advantage of only a single callback function instead of having to create a pipe of individual requests that need to be synchronized (read: big pain in the ass).

Look for jQuery deferreds. Every $.ajax call returns a 'promise' you can wait for to be resolved:

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

Then wait for them to be resolved:

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

As you mentioned you don't know how many items are in each collection, simply push each promise into an array, which can be used in $.when as follows:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM