【发布时间】:2017-10-10 18:41:16
【问题描述】:
我知道如何使用 $.when 一次执行多个 ajax 调用。 例如:
$.when( d1, d2 ).done(function ( v1, v2 ) {
console.log( v1 ); // "Fish"
console.log( v2 ); // "Pizza"
})
但是,我想在一个方法中使用它,以便我可以多次使用它来返回一个值(例如
function getDataFor(list) {
var data = [];
$.when(d1(list), d2(list)).done(function (v1, v2) {
console.log(v1);
console.log(v2);
data = [v1, v2];
});
return data;
}
什么是正确的格式?另外,在上面的例子中使用 .then 而不是 .done 本质上是没有用的,除非我打算让另一个承诺遵循那个?
edit:我不认为这是一个重复的问题。虽然我理解为什么会这样,但我真的只是想知道是否有一个开箱即用的或基于库的(例如 jquery/bluebird)包装器,如 .NET 的 WaitAll 方法,它需要一组异步调用并阻塞线程,直到它们全部完成。我已经接受这是不可能的,但我不认为这是重复的。
【问题讨论】:
-
您上面的代码将永远无法运行,因为
return data;将始终在 ajax 调用完成之前运行,因此不会填充data。在 ajax 调用完成后您希望发生的任何事情,并且依赖于它们返回的数据,必须通过“done”或“then”回调触发。您可以做的是让您的 getDataFor 方法返回由 $.when 返回的 Promise,以便外部代码可以附加其自己的 .then / .done 回调。您可以将任意数量的回调附加到一个 Promise 中。 -
我知道这行不通。我在问如何以该示例的预期效果执行某些操作。我希望该块本质上充当具有 async: false 作为属性的块。在这个遗留代码的顶部,有很多数组在初始化后没有改变,它们目前都在调用同步方法。对于我来说,有太多的依赖关系试图在给定的时间线中将它们中的 15 个链接在一起,所以我只是试图通过将它们合并在一起来至少摆脱其中的一些。我可以通过将它们设置为全局变量来解决这个问题,但是.. :(
-
即使您将它们设置为全局,如果您在它们准备好之前尝试使用它们,您就会遇到问题。除了在回调中之外,不可能知道它们是否准备好。如果您目前依靠同步来使事情正常进行,那么不幸的是,一些重构是不可避免的。返回 promise 可能是我能想到的最好的方法,那么至少你的调用代码有一些东西可以抓住,它可以添加自己的 .then 回调以在一切完成时执行。
-
我知道需要进行一些重构。这就是我正在做的事情。我不是想应用 0 努力。我知道我们有时间做什么,所以我只是想看看这样的事情是否可行。它不是。没关系。
-
您不能使用异步调用并包装它们以使它们同步。就是做不到。您的
getDataFor()函数必须使用异步方法来返回其结果(回调或承诺)。您的答案已被标记为重复,向您展示了所有各种可能性。
标签: javascript jquery ajax asynchronous jquery-deferred