如何使用 jQuery Deferred 数组?

我有一个应用程序,它要求按照一定的顺序加载数据: 根 URL,然后是模式,最后用各种数据对象的模式和 URL 初始化应用程序。当用户导航应用程序时,将加载数据对象,根据架构进行验证,并显示数据对象。当用户 CRUDs 数据时,模式提供第一步验证。

初始化有问题。我使用 Ajax 调用来获取根对象 $。然后为每个模式对象创建一个承诺数组。这样就行了。我在控制台上看到了诱饵。

然后我看到所有模式的获取,因此每个 $。Ajax ()调用工程。Fetchschema ()确实返回一个承诺数组。

然而,最终的 when ()子句从未触发,并且“ DONE”这个词从未出现在控制台上。Jquery-1.5的源代码似乎暗示“ null”作为传递给 $的对象是可以接受的。Application () ,因为如果没有传入对象,when ()将构建一个内部 Deferred ()对象来管理列表。

如果不是这样,那么应该如何管理一个 jQuery Deferred 数组呢?

    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);
});
});
58467 次浏览

你要找的人

$.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() { ... });`

您需要传递 $而不是 null,以便 $.when中的 this引用 jQuery。对于源代码来说应该无关紧要,但是它比传递 null要好。

通过用 $.when和样本 工程代替所有的 $. ajax 来模拟所有的 $. ajax

因此,这要么是 ajax 请求中的问题,要么是传递给 get _ schema 的数组出了问题。

上面的解决方案(谢谢!)不能正确地解决返回提供给延迟的 resolve()方法的对象的问题,因为 jQuery 使用单独的参数而不是数组调用 done()fail()回调。这意味着我们必须使用 arguments伪数组来获取延迟数组返回的所有已解析/被拒绝的对象,这很难看:

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

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

下面是一个受到 什么时候 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;
}
}

现在,您可以简单地传入一个延迟/允诺数组,然后在回调中返回一个已解析/拒绝对象数组,如下所示:

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

如果您正在使用 ES6版本的 javascript 有一个扩展运算符(...) ,它将对象数组转换为逗号分隔的参数。

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

更多关于 ES6扩展运营商 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator的信息请点击这里

扩展时,使用以下代码:

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)
}
}