jQuery加载未知数量的json文件并处理错误

时间:2016-03-09 00:02:18

标签: jquery json deferred

我有一个index.json文件,它返回需要加载的其他N个JSON文件的列表。它们需要使用不同的方法加载,这样当它们全部加载时,我可以一次处理它们。

服务器上可能存在或不存在其他每个JSON文件。

我正在使用以下方法加载数据,当服务器上实际存在所有文件时,该方法正常工作:

$.getJSON('index.json').then(function (response) {
    var files = response.files;
    $.when
     .apply(null, getDeferreds(files))
     .done(function() {
          //process the files
     })
    });
});

function getDeferreds(files) {
    var deferreds = [], i;
    for (i in files) {
       //file type 1
       deferreds.push(
          $.getJSON(files[i] + '_1.json')
            .then(function (response) {
              //do something
             })
       );
      //file type 2
      deferreds.push(
          $.getJSON(files[i] + '_2.json')
            .then(function (response) {
              //do something
             })
       );
    }
    return deferreds;
};

这种方法很有效,但是...... 当缺少任何文件时,即somefile_2.json(有时在文件实际存在于服务器之前将创建索引),整个过程失败,并且没有任何数据被检索。

$.getJson ($.get内,我可以使用.fail()方法检测到错误,但这并不能阻止呼叫失败,.done()永远不会被召唤。

即使缺少某些文件,我如何重构此方法以使.done()方法始终有效?

2 个答案:

答案 0 :(得分:1)

事实证明解决方案比我想象的更简单。

我的猜测是,当调用失败时,在某个过程中,延迟对象无法正确解析。

只需将return $.Deferred().resolve();添加到失败回调即可。

发布一个包含错误处理的完整解决方案,以防有人帮助:

$.getJSON('index.json').then(function (response) {
    var files = response.files;
    $.when
     .apply(null, getDeferreds(files))
     .done(function() {
          //process the files
     })
    });
});

function getDeferreds(files) {
    var deferreds = [], i;
    for (i in files) {
         deferreds.push(
           $.getJSON(files[i])
                .then(function (response) {
                   //do something
                }, function() {
                    return $.Deferred().resolve([]);
                })
         );
    };
    return deferreds;
};

答案 1 :(得分:0)

你写的内容看起来不错,前提是do something包含一个return语句,用于在promise链中(在调用者中)进一步传递数据。

你可能会考虑一些整理,并且"切蛋糕"不同的是,通过:

  • 聚合子功能中的承诺
  • 在来电者中执行所交付数据的所有处理

这是一个偏好问题,但我可能会选择写:

$.getJSON('index.json').then(function (response) {
    return getFileData(response.files);
}).then(function(dataArray) {
        // `dataArray` is an array of data items
        // Do all processing here
    });
});

function getFileData(files) {
    var promises = files.map(function(file) {
        return $.getJSON(file)
        .then(null, // No processing here
        function() {
            return $.when([]); // $.when(value) is a useful shorthand for $.Deferred().resolve(value)
        });
    });
    // By aggregating the promises here, caller(s) can be delivered an array of data items, wrapped in a single promise.
    return $.when.apply(null, promises).then(function() {
        return Array.prototype.slice.call(arguments); //convert function's `arguments` to a proper array
    });
};

当然,如果getFileData()不会从其他地方调用,您可以在调用者中执行所有操作。