【问题标题】:jQuery Deferred: $.when() with multiple objectsjQuery Deferred:具有多个对象的 $.when()
【发布时间】:2023-03-08 12:59:02
【问题描述】:

我需要一种通过回调获取不同脚本的方法。 这个方法没问题:

fetchScripts:function() {
    var _this=this;
    $.when(
        $.ajax({
            url:_this.url + 'library/script-one.js',
            type:'get',
            cache:true
        }),
        $.ajax({
            url:_this.url + 'library/script-two.js',
            type:'get',
            cache:true
        }),
        { .... },
        $.ajax({
            url:_this.url + 'library/script-n.js',
            type:'get',
            cache:true
        })
    ).then(function() {
        console.log('fetch is done');

    })
},

但我想更概括该方法,因为冗余正在增加。 是否可以向 $.when() 传递承诺? 在我的第一次尝试之下 - 但 url 总是相同的,即'script-n.js' 也许我错过了重点,您可以说明一个更“美丽”的解决方案

fetchScripts:function() {
    this.deferred=new $.Deferred();
    this.promise=this.deferred.promise();
    var _this=this;
    $.each([
        'script-one.js',
        'script-two.js',
        ( .... ),
        'script-n.js'
    ],function() {
        _this.script=this;
        _this.promise.then(function(){
            return $.ajax({
                url:_this.url + 'library/' + _this.script,
                type:'get',
                cache:true
            })
        });
    });
    $.when(
        this.promise
    ).then(function() {
        console.log('fetch is done');

    });
    this.deferred.resolve();
},

【问题讨论】:

    标签: jquery promise deferred .when


    【解决方案1】:

    你仍然需要 $.when。但相反,创建一个 Deferreds(或 Promise)数组,然后 apply 将其传递给 $.when:

    fetchScripts:function() {
        var base = this.url;
        var defaults = {
            type:'get',
            cache:true
        };
    
        var libraries = [
            'library/script-one.js',
            'library/script-two.js',
            'library/script-n.js'
        ];
    
        var deferreds = $.map(libraries, function(current) {
            var ajaxOptions = $.extend({ url:  base + current }, defaults);
            return $.ajax(ajaxOptions);
        });
    
        $.when.apply($, deferreds).then(function() {
            console.log('All done');
        });
    }
    

    除了扩展默认设置,您也可以使用$.ajax(defaults)

    【讨论】:

    • 要访问延迟值的结果,您可以使用传递给.then 的匿名函数中的arguments 魔术变量;
    • 我注意到在使用 then() 时,如果任何请求失败,尽管尚未完成,您仍将进入它的函数,而使用 done(),它只会在剩下的最后一个已经完成了,不管有没有失败。
    【解决方案2】:

    试试

    fetchScripts: function() {
        var deferred = new $.Deferred();
        var _this=this;
    
        var promises = $.map([
            'script-one.js',
            'script-two.js',
            ( .... ),
            'script-n.js'
        ], function(item, idx) {
            return $.ajax({
                url:_this.url + 'library/' + item.script,
                type:'get',
                cache:true
            })
        });
    
        $.when.apply($, promises).then(function() {
            console.log('fetch is done');
            deferred.resolve()
        });
        return deferred.promise();
    }
    

    【讨论】:

    • 我想你的意思是$.map,而不是$.each。也只是item,而不是item.script :-)
    • @RocketHazmat 是的,复制粘贴错误
    猜你喜欢
    • 2016-01-08
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多