簡體   English   中英

無法按順序獲取兩個jQuery ajax調用

[英]Cannot get two jQuery ajax calls to fire in order

我正在使用我通過POST和GET訪問的JS API。 這是一個電子通信平台(Shopify),但我不相信這個問題與平台有關。

我已經能夠編寫兩個POST請求,無論是在代碼中還是在控制台中,都可以根據需要單獨執行。 但是,我根本無法讓它們一個接一個地開火(第一個必須在第二個開始之前完成我的情況)。

第一個請求如下(這清除了購物車,不需要發送數據,只需要將URL發送到):

  function clearCart(){
    $.ajax({
      url: '/cart/clear.js',
      method: 'POST',
      success: function(){
        console.log("cleared");  
      },
     error: function(jqXHR, textStatus, errorThrown) {
          console.log('jqXHR:');
          console.log(jqXHR);
          console.log('textStatus:');
          console.log(textStatus);
          console.log('errorThrown:');
          console.log(errorThrown);
     }
    });
  }

第二個請求如下(這將一個項目和一定數量的所述項目添加到購物車,然后重定向到結帳):

function cartAdd(quantity, id){
    $.ajax({
      url: '/cart/add.js',
      method: 'POST',
      data: {
        quantity: quantity,
        id: id
      },
      success: function(data){
        console.log("added");
        window.location.href = '/checkout';
      },
      error: function(jqXHR, textStatus, errorThrown) {
          console.log('jqXHR:');
          console.log(jqXHR);
          console.log('textStatus:');
          console.log(textStatus);
          console.log('errorThrown:');
          console.log(errorThrown);
     }
    });
  }

我將它們鏈接在一起的方式看起來像這樣(變量填充正確):

$.when(
    clearCart(),
    cartAdd(variantQuantity, variantID)
);

經過大量測試,我有時似乎有正確的代碼(可能是1/10的時間),所以我被認為是一個時間問題,雖然我不能肯定地說,因為我不能一直測試對那些結果。

我唯一真正的線索是當我使用.done()時函數單獨工作,但是當我使用.success()時,它們會返回以下內容:

SyntaxError: Unexpected token :
    at eval (<anonymous>)
    at jquery-1.10.2.min.js?1013630…:4
    at Function.globalEval (jquery-1.10.2.min.js?1013630…:4)
    at text script (jquery-1.10.2.min.js?1013630…:6)
    at On (jquery-1.10.2.min.js?1013630…:6)
    at k (jquery-1.10.2.min.js?1013630…:6)
    at XMLHttpRequest.r (jquery-1.10.2.min.js?1013630…:6)

有幫助嗎?

更新我實際上能夠通過顯式指定'json'的數據類型來解決語法錯誤。 無論如何,這兩個功能仍然表現不正常,有時只能以正確的順序工作。

如果您的評估是正確的,您可以簡單地使函數同步運行,以確保僅在第一個函數執行時調用第二個函數。 這是你如何做到的:

  function clearCart(){
    $.ajax({
      url: '/cart/clear.js',
      method: 'POST',
      async: false,
      success: function(){
        console.log("cleared");  
      },
     error: function(jqXHR, textStatus, errorThrown) {
          console.log('jqXHR:');
          console.log(jqXHR);
          console.log('textStatus:');
          console.log(textStatus);
          console.log('errorThrown:');
          console.log(errorThrown);
     }
    });
  }

請注意async屬性,它告訴瀏覽器在調用下一個函數之前等待請求完成。 你不需要在第二個函數上設置它,因為你不希望在那之后執行任何操作。

另外,我建議您在第一個函數中使用回調而不是async=false因為async往往會損害用戶體驗。

參考: http//api.jquery.com/jquery.ajax/

clearCart()cartAdd()函數返回沒有值或jQuery promise,請參閱cartAdd() 為什么值未定義鏈接到Promise? return $.ajax()調用,鏈.then()來調用第二個函數。

function clearCart() {
  return $.ajax({
    url: '/cart/clear.js',
    method: 'POST'
  });
}

function cartAdd(quantity, id) {
  return $.ajax({
    url: '/cart/add.js',
    method: 'POST',
    data: {
      quantity: quantity,
      id: id
    }
  })
}

function handleError(jqXHR, textStatus, errorThrown) {
  console.log('jqXHR:');
  console.log(jqXHR);
  console.log('textStatus:');
  console.log(textStatus);
  console.log('errorThrown:');
  console.log(errorThrown);
}


clearCart()
  .then(function() {
    console.log("cleared")
    return cartAdd(variantQuantity, variantID)
  })
  .then(function() {
    console.log("added");
    window.location.href = '/checkout';
  })
  .fail(handleError);

返回承諾,使其像鏈接一樣使用。

  function clearCart() {
    return $.ajax({
      url: '/cart/clear.js',
      method: 'POST',
      success: function() {
        console.log("cleared");
      },
      error: function(jqXHR, textStatus, errorThrown) {
                // error handler
      }
    });
  }

  function cartAdd(quantity, id){
    return $.ajax({
      url: '/cart/add.js',
      method: 'POST',
      data: {
        quantity: quantity,
        id: id
      },
      success: function(data){
        console.log("added");
        window.location.href = '/checkout';
      },
      error: function(jqXHR, textStatus, errorThrown) {
                // error handler
     }
    });
  }

現在調用這樣的函數

  clearCart().done( function(){
    // after cart is empty, code goes below

    // Example code to add item to cart
    cartAdd( 3, 1);

  }).fail(function(){

    // clear cart failed
    // put handler here if required
  })

放置async選項的問題是,此選項會使所有內容都掛起,直到響應。

對於這些情況:首先我們在頁面的ready函數上調用ajax並將它們放在不同的sessionStorage ,然后放在我們的函數中(這將是ready或者至少函數已經沒有ready ,只需將其調用ready )我們檢查值。 如果它們為null,我們在特定時間(例如3s)之后再次調用該函數,使用setTimeout並在一段時間后設置值,我們可以在函數中使用它們

示例代碼:

$(document).ready(function(){
    sessionStorage.setItem("firstApi",JSON.stringify(callFirstAjax()));
    sessionStorage.setItem("secondApi",JSON.stringify(callSecondAjax()));

    doSomething();
});

function doSomething() {
    var firstApi = sessionStorage.get("firstApi");
    var secondApi = sessionStorage.get("secondApi");
    if(firstApi == null || secondApi == null) {
        setTimeout(function() {
            firstApi = null;
            secondApi = null;
            doSomething();
         }, 3000);
    }
    // rest of function based on two variable values
}

順便說一句,sessionStorage對於每個瀏覽器都是不同的,如果當前窗口關閉了你不能,你必須再次設置它。 如果您想使用類似的東西,但可以訪問所有瀏覽器窗口(您的網站在其中打開),請使用localStorage而不是sessionStorage

還有其他方法,而不是使用棄用的方法“async:false”。 有時可能會導致嚴重后果。 但是,您可以使用它。 但我會建議你通過其他方式來完成這項任務:

第一:使用deferred.then()方法,例如,如果你有兩個ajax調用:

  function clearCart(){
   $.ajax({
   url: '/cart/clear.js',
   method: 'POST',
   .... });
  }

  function cartAdd(quantity, id){
   $.ajax({
   url: '/cart/add.js',
   method: 'POST',
   data: {
     quantity: quantity,
     id: id
   },
   .....});
 }

然后只使用then方法並返回第二個ajax調用作為promise:

$.when(clearCart(....)).then(function(){ return cartAdd(....)});

它會產生你對ajax Calls的預期或鏈接。

另一種方法是將ajax調用放在ajax的成功塊中。

function clearCart(){
   $.ajax({
   url: '/cart/clear.js',
   method: 'POST',
   success: function(data){
      cartAdd(....);
   }
   ...... });
  }

這兩種方法都會產生您的預期,而且它們的優點是它們不是被棄用的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM