你如何使用jQuery Deferreds的数组?

我有一个应用程序,需要按照一定的顺序加载数据:根URL,然后是模式,然后用各种数据对象的模式和URL来初始化应用程序。 当用户导航应用程序时,数据对象被加载,根据模式进行validation并显示。 当用户CRUD数据时,模式提供首过validation。

我在初始化时遇到问题。 我使用Ajax调用获取根对象$ .when(),然后创build一个承诺数组,每个模式对象一个。 这样可行。 我在控制台中看到提取。

然后我看到所有模式的提取,所以每个$ .ajax()调用的作品。 fetchschemas()的确会返回一个promise数组。

但是,最后when()子句永不会触发,单词“DONE”永远不会出现在控制台上。 jquery-1.5的源代码似乎意味着可以将“null”作为传递给$ .when.apply()的对象来接受,因为when()将构build一个内部的Deferred()对象来pipe理列表,如果没有对象通过了。

这工作使用Futures.js。 如何pipe理jQuery Deferreds数组?如果不是这样?

var fetch_schemas, fetch_root; fetch_schemas = function(schema_urls) { var fetch_one = function(url) { return $.ajax({ url: url, data: {}, contentType: "application/json; charset=utf-8", dataType: "json" }); }; return $.map(schema_urls, fetch_one); }; fetch_root = function() { return $.ajax({ url: BASE_URL, data: {}, contentType: "application/json; charset=utf-8", dataType: "json" }); }; $.when(fetch_root()).then(function(data) { var promises = fetch_schemas(data.schema_urls); $.when.apply(null, promises).then(function(schemas) { console.log("DONE", this, schemas); }); }); 

你在找

 $.when.apply($, promises).then(function(schemas) { console.log("DONE", this, schemas); }, function(e) { console.log("My ajax failed"); }); 

这也将工作(对于一些工作价值,它不会修复破碎的Ajax):

 $.when.apply($, promises).done(function() { ... }).fail(function() { ... });` 

你需要传递$而不是nullthis $.when引用jQuery 。 对源代码应该没有问题,但是最好传递null

嘲笑你所有的$ .ajax通过用$.when和样本工作

所以这可能是你的ajax请求中的一个问题,或者是你传给fetch_schemas的数组。

上面的解决方法(谢谢!)没有正确地解决回收提供给deferred的resolve()方法的对象的问题,因为jQuery使用单个参数调用done()fail()callback,而不是数组。 这意味着我们必须使用arguments pseudo-array来获取由延迟数组返回的所有parsing/拒绝对象,这很丑陋:

 $.when.apply($, promises).then(function() { var schemas=arguments; // The array of resolved objects as a pseudo-array ... }; 

由于我们传入了一个延迟数组,所以返回结果数组将会很好。 取回一个实际的数组而不是一个伪数组也是很好的,所以我们可以使用像Array.sort()这样的方法。

这个解决scheme是由when.jswhen.all()方法来解决这些问题的:

 // Put somewhere in your scripting environment if (jQuery.when.all===undefined) { jQuery.when.all = function(deferreds) { var deferred = new jQuery.Deferred(); $.when.apply(jQuery, deferreds).then( function() { deferred.resolve(Array.prototype.slice.call(arguments)); }, function() { deferred.fail(Array.prototype.slice.call(arguments)); }); return deferred; } } 

现在,您可以简单地传递一个deferreds / promise数组,并在您的callback中取回已parsing/已拒绝的对象数组,如下所示:

 $.when.all(promises).then(function(schemas) { console.log("DONE", this, schemas); // 'schemas' is now an array }, function(e) { console.log("My ajax failed"); }); 

如果您使用的是JavaScript的ES6版本有一个传播运算符(…),它将对象数组转换为逗号分隔的参数。

 $.when(...promises).then(function() { var schemas=arguments; }; 

更多关于ES6传播运算符https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator在这里find

用这个代码扩展:

 var rawWhen = $.when $.when = function(promise) { if ($.isArray(promise)) { var dfd = new jQuery.Deferred() rawWhen.apply($, promise).done(function() { dfd.resolve(Array.prototype.slice.call(arguments)) }).fail(function() { dfd.reject(Array.prototype.slice.call(arguments)) }) return dfd.promise() } else { return rawWhen.apply($, arguments) } }