许多请求最终回调,订单不可靠?

时间:2016-10-29 14:04:11

标签: javascript jquery promise

我试图想出一个资源加载器,如果你愿意的话,它将加载许多远程资源,然后执行最终的回调(比如根据这些请求中的检索数据渲染DOM)。

这里的功能是:

var ResourceLoader = function () {

    this.requests = new Array();
    this.FinalCallback;

    this.Add = function (request) {
        this.requests.push(request);
    };

    this.Execute = function() {

        for (var x = 0; x < this.requests.length ; x++) {

            var success = this.requests[x].success;

            //if this is the last of the requests...
            if (x == (this.requests.length - 1) && this.FinalCallback) {

                $.when($.ajax({
                            url: this.requests[x].url,
                            dataType: 'json',
                            error: this.requests[x].error,
                            method: 'GET'
                        }).done(success)).then(this.FinalCallback);
            }
            else {

                $.ajax({
                    url: this.requests[x].url,
                    dataType: 'json',
                    error: this.requests[x].error,
                    method: 'GET'
                }).done(success);                
            }

        }

    };
};

以下是我如何使用它:

var apiUrl = Utilities.Api.GetWebApiUrl();
var loader = new Utilities.ResourceLoader();

loader.Add({
    url: apiUrl + 'regions/get',
    success: function (results) {
        Filters.Regions = results;
    }
});

loader.Add({
    url: apiUrl + 'currentfactors/get/83167',
    success: function (results) {
        Filters.NbrEmployees = results;
    }
});

loader.Add({
    url: apiUrl + 'currentfactors/get/83095',
    success: function (results) {
        Filters.Industries = results;
    }
});


loader.FinalCallback = RenderBody;
loader.Execute();

function RenderBody() {
    console.log('render...');
}

显然,我期待最后执行RenderBody。但那不是发生的事情。具有讽刺意味的是,我记得之前做过类似的事情,但丢失了代码......看起来我在这里有一个脑筋。

2 个答案:

答案 0 :(得分:2)

正如您已使用标记的 - 这是一个使用Promise.all

的非常干净的解决方案
this.Execute = function() {
  Promise.all(this.requests.map(function(request) {
    return $.ajax({
        url: request.url,
        dataType: 'json',
        error: request.error,
        method: 'GET'
    }).done(request.success);
  })).then(this.FinalCallback);
};

或......在

时使用JQuery
this.Execute = function() {
  $.when.apply($, this.requests.map(function(request) {
    return $.ajax({
        url: request.url,
        dataType: 'json',
        error: request.error,
        method: 'GET'
    }).done(request.success);
  })).then(this.FinalCallback);
};

答案 1 :(得分:0)

Es6 Promise为您的问题提供了解决方案,除非加载资源组是抽象的特定目标,否则无需重新发明它。为每个资源请求设置一个Promise对象,使用构造函数为XHR分配解析和拒绝回调。保留Iterable结果的集合(任何individualPromise.then(individualCallback)都可以)。您的最终产品是Promise.all(collectionOfPromises).then(finalCallback)获得的。