你如何使用jQuery Deferreds的数组?

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

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

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

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

这工作使用Futures.js。 如何管理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()回调,而不是数组。 这意味着我们必须使用arguments pseudo-array来获取由延迟数组返回的所有解析/拒绝对象,这很丑陋:

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

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

这个解决方案受到了when.js的解决这些问题的when.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");
});

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

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

关于ES6传播运算符的更多信息https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator find here

链接地址: http://www.djcxy.com/p/55319.html

上一篇: How do you work with an array of jQuery Deferreds?

下一篇: When should I use jQuery deferred's "then" method and when should I use the "pipe" method?