【问题标题】:Callback when AJAX calls are done using jQuery when使用 jQuery 完成 AJAX 调用时的回调
【发布时间】:2026-01-20 23:05:02
【问题描述】:

我无法使回调正常工作。这是我想要实现的目标:我有 2 件商品要添加到购物车中,因此我发出了 2 个异步 POST 请求。一旦这两个 POST 请求完成,我想更新购物车的部分视图。问题是似乎只有 1 件商品被添加到购物车中。当我调试它时,添加了 2 个项目。任何建议或帮助都会很棒。提前致谢!

这是我的代码:

var cart = []

function AddToCart(input) {
  return $.ajax({
    method: 'POST',
    url: '/cart/add.js',
    data: input,
    dataType: 'json'
  })
  .done(function(data) {
    return data;
  });
}  

$("#addToCart").click(function() {
  $('#capsContainer input:checked').each(function() {
    var cartItem = {
      id: $(this).val(),
      quantity: 1
    }

    cart.push(cartItem);
  });

  var test1 = AddToCart(cart[0]);
  var test2 = AddToCart(cart[1]);

  $.when.apply(test1, test2).done(function() {
        $.getJSON('/cart.js', function(data) {
        $('.cart-item-count').text(data.item_count);
        $('.cart-item-price').html(formatMoney(data.total_price));      
        ShowCart();
    });
  })
});

【问题讨论】:

  • $.ajax 返回一个已经被延迟的jqXHR 对象,因此这里不建议使用$.when
  • jQuery $.post deferred的可能重复
  • @SterlingArcher 我在使用 $.when 之前这样做了,其中 $.when 中的回调在 done() 中,但它似乎只处理了一个 POST 请求。你如何让它等到两个 POST 请求都完成?
  • 您可以考虑使用名为 ajaxq.js 的库,该库可用于将 ajax 请求分组排队,然后您可以将请求嵌入到 $ 的回调部分中.postq() 请求遵循与 $.post() 相同的语法

标签: javascript jquery ajax shopify .when


【解决方案1】:

部分问题是您使用 ajax 请求可能发生在代码碰巧处理这些执行之前或之后。由于它们是异步的,因此它们可能会在任何其他代码在页面上运行之前触发/返回,具体取决于浏览器的 Javascript 解析器如何决定执行代码。您可以使用一个名为 ajaxq.js

的小型 600 字节库来控制整个交互,而不是尝试在异步 ajax 请求上使用回调

ajaxq.js 本质上就像 jQuery 的 $.post() 方法一样工作,只是您还可以按名称指定多个队列以异步执行,并为它们附加回调或其他。

这是一个快速示例,说明如何使用此库设置 Ajax 购物车预览。

/* queue up an AJAX request */
$.postq("set_data", "add_items.php", {"itemID": someItemID, "customerID": customerID },
  function(result1) {


  /* perform new request at the end of first request */

  $.postq("get_data", "get_items.php", { "id": customerID }, 
      function(result2) {

    /* add in code to perform at the end of the second ajax POST request */

  }); // end of request 2

}); // end of request 1

这是您使用 ajaxq.js 库的示例:

function AddToCart(input) {
   $.postq("add_item", "/cart/add/js", input, function(result) {
        preview_items();
    }, "json");

}  

function preview_items() {
 $.getJSON('/cart.js', function(data) {
        $('.cart-item-count').text(data.item_count);
        $('.cart-item-price').html(formatMoney(data.total_price));      
        ShowCart();
}


$(document).ready(function() { 
  $("#addToCart").on("click" function() {
    $('#capsContainer input:checked').each(function(elem) {
      var cartItem = {
        id: $(this).val(),
       quantity: 1
      }

      cart.push(cartItem);
    });

    var test1 = AddToCart(cart[0]);
    var test2 = AddToCart(cart[1]);

  });

【讨论】:

  • 我想当我发现它时我确实说了同样的话——似乎是解决与 ajax 及其异步方式相关的许多问题
【解决方案2】:

您的 AddToCart 方法已经返回一个延迟对象。您正在调用 .done 方法两次。

我猜你的代码应该是这样的。

var cart = []

function AddToCart(input) {
  return $.ajax({
    method: 'POST',
    url: '/cart/add.js',
    data: input,
    dataType: 'json'
  });
}  

$("#addToCart").click(function() {
  $('#capsContainer input:checked').each(function() {
    var cartItem = {
      id: $(this).val(),
      quantity: 1
    }

    cart.push(cartItem);
  });

  var test1 = AddToCart(cart[0]);
  var test2 = AddToCart(cart[1]);

  $.when(test1, test2).done(function() {
        $.getJSON('/cart.js', function(data) {
            $('.cart-item-count').text(data.item_count);
            $('.cart-item-price').html(formatMoney(data.total_price));      
            ShowCart();
        });
      })
});

【讨论】:

  • 我试过了,但每次单击“添加到购物车”按钮时它仍然会添加一项。它添加这两个项目的唯一时间是在我调试它时。好奇怪