gpt4 book ai didi

javascript - 在 JQuery $.when 调用中处理可变数量的延迟请求的更好方法?

转载 作者:行者123 更新时间:2023-11-30 05:42:07 26 4
gpt4 key购买 nike

我正在编写一个应用程序,在某个时候需要在继续之前获得一些请求的结果。这似乎是使用 JQuery 的 when 的可能候选者。例如:

 // requests is an array of Deferreds
$.when.apply(null, requests).done(function(results) {
// process results
}

要注意的是,请求的数量可能是 1 个,也可能更多,when 函数以不同方式处理这些情况。只有一个请求,回调获取标准 (data, textStatus, jqXHR) 参数,但是当提供多个请求时,回调接收一系列参数:每个请求的 (data, textStatus, jqXHR) 值数组。令人沮丧的是,JQuery 似乎将请求的单例数组视为与单个参数请求相同,这意味着必须以不同方式处理这种情况。

我能想出的最好的办法来梳理这些案例,感觉有点笨拙,并且由于不同案例中结果参数的微妙之处,我花了一段时间才弄清楚,然后是请求数组的菜鸟陷阱需要被包裹在一个函数中,以便可以在闭包中访问它。

$.when.apply(null, function (){return requests;}()).done(function(results) {
if (requests.length == 1) {
processResults(results);
} else {
for (var i=0; i < arguments.length; i++)
processResults(arguments[i][0]);
}
moreStuff();
});

还有比这更好或更优雅的方式吗?

最佳答案

我看到这是一个较旧的问题,但最近我遇到了这个问题,我在搜索该问题时遇到了这个问题。我最终创建了自己的解决方案,所以我想我会在这里分享它作为答案。

简而言之,$.when() 的设计确实不适合用于动态数量的参数。事实上,动态论证有点糟糕。它既难用又行为不一致。

似乎 ES6 promise 规范的设计者同意,因为 Promise.all() 的模拟设计不同并且解决了这两个问题。所以,我能想到的处理 jQuery 的 $.when() 问题的最好办法是制作一个遵循 Promise.all() 规则的新版本因此使用起来更简单。 jQuery Ajax promise 返回一个包含三个值的数组,这些值以您提到的奇怪方式与 $.when() 交互,这让生活变得更加复杂。

因此,$.when() 有两个主要更改以生成 $.all():

  1. 让它接受一组 promise ,而不是单独的 promise 参数。这使您不必使用 .apply() 只是为了向 $.all() 发送可变数量的 promise 。

  2. 使 $.all() 的结果始终为数组形式,无论最初传入了多少 promise。这就是您在你的问题。幸运的是,不需要很多代码就可以解决这个问题。

可以这样做:

$.all = function (promises) {
if (!Array.isArray(promises)) {
throw new Error("$.all() must be passed an array of promises");
}
return $.when.apply($, promises).then(function () {
// if single argument was expanded into multiple arguments, then put it back into an array
// for consistency
if (promises.length === 1 && arguments.length > 1) {
// put arguments into an array
return [Array.prototype.slice.call(arguments, 0)];
} else {
return Array.prototype.slice.call(arguments, 0);
}
})
};

你像$.when()一样使用它,除了你总是传递$.all()一个单一的参数,它是一个promises数组(不需要.apply() )并且它总是解析为一个结果数组的单个参数(更容易迭代 promise 结果的动态数字并且它总是一致的)。

因此,如果您有一个任意长度的 ajax promise 数组:

var promises = [url1, url2, url3].map(function(url) {
return $.get(url);
});


$.all(promises).then(function(results) {
// results are always consistent here no matter how many promises
// were originally passed in, thus solving your original problem
for (var i = 0; i < results.length; i++) {
console.log(results[i]);
}
});

关于javascript - 在 JQuery $.when 调用中处理可变数量的延迟请求的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20233478/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com