简体   繁体   English

暂停Jquery.each循环以确保代码完全执行?

[英]Pausing a Jquery.each loop to ensure code is fully executed?

Quick question - I've got a $.each loop, with a function call inside with a callback function 快速提问-我有一个$ .each循环,在其中带有回调函数的函数调用

what can i put inside of that callback function to continue the loop 我可以在该回调函数中放入什么以继续循环

$.each(product, function () {
    AddToCart($(this), function () {

    });
});

right now - if it loops through 5 products, only the last one gets added to the cart 现在-如果它遍历5个产品,则只有最后一个被添加到购物车

i need a way of pausing the loop to ensure the product is added to the cart before adding the next one 我需要一种暂停循环的方式,以确保在添加下一个产品之前将产品添加到购物车

thanks! 谢谢!

Here is the AddToCart function: 这是AddToCart函数:

function AddToCart(product, callback) {
            //Get the product ID and info
            var product = product;
            var productid = product.children(".productId").val();
            var productName = product.children(".productName").val();
            var productPage = product.children(".productPage").attr("href");
            var productImage = product.find(".productImage").attr("src");
            var productPrice = product.find(".productPrice").val();
            var productMSRP = product.find(".productMSRP").val();

            var productList = $("#productList");
            var exists = false;
            listItems = $("#productList").find("li");
            // Loop through to see if the product has already been added
            listItems.each(function (idx, li) {
                var item = $(li);
                var itemId = item.children(".productId").val();
                if (itemId == productid) {
                    exists = true;
                    //find its quantity
                    var quantity = item.children(".quantity").html();

                    //increment the quantity
                    quantity = parseInt(quantity) + 1;
                    item.children(".quantity").html(quantity);
                }
            });

            if (!exists) {
                var listItem = "<li>" +
                                    "<a href='" + productPage + "'><img height='80px' src='" + productImage + "'/></a>" +
                                    "<input type='button' value='X' class='cartRemoveBtn'/>" +
                                    "<span class='quantity'>1</span>" +
                                    "<div class='tooltip_info'>" +
                                    "<span class='tooltip_name'>" + productName + "</span>" +
                                    "<span class='tooltip_price'>Our Price: $" + parseFloat(productPrice, 10).toFixed(2) + "</span>" +
                                    "<span class='tooltip_msrp'>List Price: $" + parseFloat(productMSRP, 10).toFixed(2) + "</span>" +
                                    "<span class='tooltip_savings'>You Save: $" + parseFloat(productMSRP - productPrice, 10).toFixed(2) + "</span>" +
                                    "</div>" +
                                    "<input type='hidden' class='productId' value='" + productid + "' />" +
                                    "<input type='hidden' class='productPrice' value='" + productPrice + "' />" +
                                    "<input type='hidden' class='productMSRP' value='" + productMSRP + "' />" +
                               "</li>";


                productList.prepend(listItem);
            }
            OpenCart();
            updateTotals();
            initializeCart();
            refreshTooltips();
            $.post('/Store/Cart/AddToCart/' + productid, function () {
                callback();
            });
            return false;
        }

$.each is a synchronous function, so as long as the actions in AddToCart are synchronous then each call will complete before the next one is invoked. $ .each是一个同步函数,因此只要AddToCart中的操作是同步的,则每个调用将在调用下一个调用之前完成。

... that said, if you're doing something like posting an asynchronous AJAX request in AddToCart, and you want to make sure each request finishes before posting the next one, than $.each() is not the right approach. ...也就是说,如果您正在执行类似在AddToCart中发布异步AJAX请求的操作,并且想要确保每个请求在发布下一个请求之前都已完成,那么$ .each()是不正确的方法。 Instead, you'll need to have your items in a queue (array) that you pull from each time a request completes. 取而代之的是,您需要将项目放入每次请求完成后要拉出的队列(数组)中。

The $.each function is already synchronous meaning that it is stepping through each product one at a time, first to last. $ .each函数已经是同步的,这意味着它一次一次地逐步浏览每个产品。 The first function call is blocking the second function call until the first function returns. 第一个函数调用将阻塞第二个函数调用,直到第一个函数返回。

Here is a working pseudo-code example: 这是一个工作的伪代码示例:

function AddToCart(item, callback){
  alert(item);
};

var products = [1,2,3,4,5];

$.each(products, function(index, product){
  AddToCart(product);
});

Possible Issue 可能的问题

The AddToCart function is registering a callback on post (an asynchronous call from inside of AddToCart) which means that it is returning before the post function has had time to complete. AddToCart函数在发布时注册一个回调(AddToCart内部的异步调用),这意味着它在发布函数有时间完成之前返回。 I don't know what your callback is doing but this is probably completing all of the AddToCart calls before the first post is returning from '/Store/Cart/AddToCart/' 我不知道您的回调函数在做什么,但这可能会在第一条帖子从“ / Store / Cart / AddToCart /”返回之前完成所有AddToCart调用。

Solution

Run the code that depends upon the return of the post inside of the callback of the AddToCart function. 运行取决于AddToCart函数的回调内部的帖子返回的代码。

Alternate Solution 替代解决方案

Use another form of stepping through the products... this uses the callback of AddToCart to call the next product addition. 使用另一种形式逐步浏览产品...这使用AddToCart的回调调用下一个产品添加。

function AddEachToCart(products) {
  // ensure products is not a js Array
  products = $(products).toArray();
  if (products.length > 0) 
    AddToCart(products.shift(), function(){AddEachToCart(products)});
};

$.each could be appropriate here; $。在这里可能是合适的; however, the issue is that since an asynchronous call is involved, you cannot expect that you can directly reference the current value from within the asynchronous handler. 但是,问题在于,由于涉及到异步调用,所以不能指望可以从异步处理程序中直接引用当前值。 You have to pass the object you're trying to manipulate within the async callback to the async call as a reference. 您必须将要在异步回调中尝试操作的对象传递给异步调用作为参考。

Hope that makes sense. 希望有道理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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