如何从延迟对象返回函数

时间:2014-04-28 04:23:44

标签: javascript jquery ajax deferred

我有一个函数,它传递一个URL列表(在这种情况下是一个json文件列表),它为每个资源进行异步ajax调用,一旦完成,就返回一个包含内容的对象。

function loadModels(modelList){
    var modelObject = {}

    for(model in modelList){
        var urlPath = modelList[model].indexOf(".json") > -1 ? 'model/'+modelList[model]+'json' : 'model/'+modelList[model]+'.json';
        $.ajax(urlPath).done(function(jsonData){
            modelObject[modelList[model]] = jsonData;
        });
    }   

    console.log(modelObject);
    return modelObject;
}

麻烦的是,控制台总是记录Object {},因为函数在延迟对象解析之前返回。如果我设置async: false然后它工作正常,但我不希望请求彼此等待。

如何强制函数在返回之前等待并仍然异步调用?

编辑:链接中的延迟解决方案不是一个完整的答案。我遇到的问题与闭包有关。这是工作代码块:

function loadModels(modelList, callback){
var promises = [];

for(model in modelList){
    (function(){
        var currentModel = modelList[model];
        var urlPath = currentModel.indexOf(".json") > -1 ? 'model/'+currentModel+'json' : 'model/'+currentModel+'.json';
        var promise = $.ajax(urlPath);
        log('pulling model: ' + currentModel);
        promise.done(function(jsonData){
            modelObject[currentModel] = jsonData;
            log('model pulled: ' + currentModel);
        });
        promises.push(promise);
    })();
}

$.when.apply(null, promises).done(function() {
    callback(modelObject);
});
}

2 个答案:

答案 0 :(得分:2)

您可以使用jQuery.when()等待所有承诺解决,然后再继续...

var promises = [];

for(model in modelList){
    var urlPath = modelList[model].indexOf(".json") > -1 ? 'model/'+modelList[model]+'json' : 'model/'+modelList[model]+'.json';
    var promise = $.ajax(urlPath);
    promises.push(promise);
    promise.done(function(jsonData){
        modelObject[modelList[model]] = jsonData;
    });
}   

$.when.apply(null, promises).done(function() {
    console.log(modelObject);
});

答案 1 :(得分:0)

当最后一个ajax-done事件结束时触发一个事件并将你的对象传递给事件数据

以及您需要数据处理该事件的位置。

$.event.trigger({
            type: "afterMyAjaxDone",
            data: MyDataObject
        });

$(document).on('afterMyAjaxDone', function (e) {
    var MyDataObject = e.data;
}