[英]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往往會損害用戶體驗。
從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.