2017-07-15 56 views
1

我正在使用通过使用POST和GET访问的JS API。这是一个电子通讯平台(Shopify),但我不认为这个问题与平台有关。无法按顺序触发两个jQuery ajax调用

我已经能够编写两个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'来解决语法错误。无论如何,这两个功能仍然行为不正常,有时只按正确的顺序工作。

+0

根据这个答案,你是否无法在'success'响应中调用'addCart()'? https://stackoverflow.com/questions/10089447/jquery-ajax-request-inside-ajax-request – mrbubbles

回答

1

如果你的评估是正确的,你可以简单地使这些函数同步运行,以确保你的第二个函数只有在第一个函数被执行时才被调用。这里是你如何能做到这一点:

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,因为异步往往会伤害用户体验。

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

+0

完美的作品。不胜感激。 – AKor

0

没有价值或jQuery的承诺是无论从clearCart()cartAdd()函数返回,见Why is value undefined at .then() chained to 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); 
0

async选项的问题是,这个选项会使一切挂直到响应。

对于这些情况:首先我们呼吁页ready功能ajaxes并把它们放在不同的sessionStorage秒,然后在我们的函数(这将是ready或至少功能超出ready和刚出来称它为ready)我们检查这些值。如果他们是空的,我们在特定的时间后再次调用该函数usning setTimeout(3S为例),并经过一段时间的值设置,我们可以在我们的函数中使用它们

示例代码:

$(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

0

返回承诺,使其使用像链接。

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 
    }) 
0

还有其他的方法,而不是使用方法已过时“异步:假”。有时可能会导致严重的后果。但是,您可以使用它。 但我建议你其他的方式来实现这一任务:如果你有两个Ajax调用使用deferred.then()例如方法 :

首先

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 
    }, 
    .....}); 
} 

就用那么方法和返回第二个阿贾克斯呼吁作为承诺:

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

这将导致你期望或链接ajax调用。

另一种方法是将ajax调用放入ajax的成功块中。

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

这两种方法都会产生您所期望的效果,而关于它们的好处在于它们不是弃用的方法。