2017-03-06 54 views
0

我有兩個函數:addItemremoveItem表示POST給定的URL。這些AJAX調用工作正常。但是,他們需要同步。我試圖通過使用.when來使它們同步。我的代碼基本上是這樣的:2 AJAX調用時使用

$.when(additem()).done(removeItem()); 

但這似乎並沒有被正確地工作,請求被同時被解僱。

我也試圖把的功能之一的請求的complete,像這樣:

$.ajax({ 
    type: "POST", 
    url: '/cart/update.js', 
    data: {updates: updates}, 
    dataType: 'json', 
    complete: removeItem() 
}); 

但是,這似乎並沒有工作或者..什麼是完成一個正確的方式在開始下一個AJAX請求之前?

謝謝

+0

使用與'的removeItem()'執行函數的括號。要傳遞迴調函數,請不要使用這些括號。 – 4castle

+0

您可以使用['async'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)和['await'](https://developer.mozilla .org/en-US/docs/Web/JavaScript/Reference/Operators/await) –

回答

1

引用一個函數並調用它是有區別的。

  • 要引用一個函數,只能使用它的名字。
  • 要調用函數,請使用其名稱,然後再使用括號。

當設置回調(異步或不是異步)時,您想引用該函數,而不是調用它。在第二次函數調用之後包含括號會立即發生呼叫。

試試這個:

$.when(additem()).done(removeItem); 

或者:

$.ajax({ 
    type: "POST", 
    url: '/cart/update.js', 
    data: {updates: updates}, 
    dataType: 'json', 
    complete: removeItem 
}); 

如果你需要傳遞參數給回調,則必須使用括號,但要避免調用,函數應該被包裹在另一個功能聲明如下:

$.when(additem()).done(function(){ 
    removeItem(<arguments here>); 
}); 

或者:

$.ajax({ 
    type: "POST", 
    url: '/cart/update.js', 
    data: {updates: updates}, 
    dataType: 'json', 
    complete: function(){ 
    removeItem(<arguments here>); 
    } 
}); 
+1

或者只是'complete:removeItem' – 4castle

+0

謝謝!但是如果我必須將一個參數傳遞給'removeItem' ..我會像在編輯之前那樣做它嗎?我必須傳遞該項目的'id'才能刪除.. – ToddT

+1

@ToddT是的,要傳遞參數,您將需要我的先前語法。我會把它作爲一個選項放回 –

1

問題在於你如何給他們打電話。您立即調用這兩個函數,而不是將它們作爲參數傳遞給$.whendone

由於$.ajax返回Promise(或類似Promise的對象),因此可以完全省略$.when

function addItem() { 
 
    // $.ajax returns a Promise-like object 
 
    return new Promise(function(resolve, reject) { 
 
    console.log('Adding an item...'); 
 
    setTimeout(function() { 
 
     console.log('Item has been added'); 
 
     resolve(); 
 
    }, 2000); 
 
    }); 
 
} 
 

 
function removeItem() { 
 
    return new Promise(function(resolve, reject) { 
 
    console.log('Removing an item...'); 
 
    setTimeout(function() { 
 
     console.log('Item has been removed'); 
 
     resolve(); 
 
    }, 2000); 
 
    }); 
 
} 
 

 
// Promises implement a `then` function which runs when the promise resolves 
 
addItem() 
 
    .then(removeItem);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

1

可以使用jquery-ajaxQueue

或修改代碼:

$.ajax({ 
    type: "POST", 
    url: '/cart/update.js', 
    data: {updates: updates}, 
    dataType: 'json', 
    complete: removeItem 
}); 

記住一件事是,如果你的函數, 這意味着後看到一個括號「執行」,所以如果你設置removeItem()爲回調它不會被稱爲預期。它將在您將其設置爲complete時調用。

0

其他答案已經解決了這個事實,即您正在調用該函數並傳遞結果而不是傳遞要調用的函數。此答案旨在強調ECMAScript 2017語言規範(ES8)中引入的新功能asyncawait

正如你可以從下面的代碼片段看到的,每行在執行之前等待前一行完成;而沒有異步和等待,每行都會執行而不等待異步調用完成。

const asyncFunc = text => new Promise((resolve, reject) => { 
 
    setTimeout(() => resolve(text), 1000) 
 
}) 
 

 
async function main() { 
 
    const hello = await asyncFunc("hello") 
 
    console.log(hello) 
 
    const world = await asyncFunc("world") 
 
    console.log(world) 
 
} 
 

 
main()