2017-03-06 57 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()