0

我有一个这样的xml文件

<users>
    <user>
        <name>LOREM</name>
        <pic>LOREM</pic>
        <post>www.URL.com/info.json</post>
    </user>
    <user>
        <name>LOREM</name>
        <pic>LOREM</pic>
        <post>www.URL.com/info.json</post>
    </user>
</users>

我用jquery解析这个xml,所以:

var data = {};
$.get('xmlfile.xml', function(xml){
    var oXML = $(xml);

    oxml.find('user').each(function(i){
        data[i].name = $(this).attr('name');
        data[i].pic = $(this).attr('pic');
        data[i].post = /* i must load a json file with all posts here*/
    });

});

这些帖子位于外部 json 文件中。我试图像这样在加载 xml 时加载 json

var data = {};
$.get('xmlfile.xml', function(xml){
    var oXML = $(xml);

    oxml.find('user').each(function(i){
        data[i].name = $(this).attr('name');
        data[i].pic = $(this).attr('pic');
        data[i].post = $.getJSON($(this).attr('post'), function(data){
            retrun data;
        });
    });

});

但它不起作用。的值为data[i].post空。你有在加载 xml 上加载 json 的想法吗?

4

2 回答 2

2

$.getJSON是异步的,因为 AJAX 是异步的。您只能在success回调内部访问 AJAX 调用的结果。在您的示例中,您试图将$.getJSON调用的返回值分配给data[i].post变量。但这不可能起作用,因为该值可能在很久以后才可用,只有在 AJAX 调用成功之后。

所以你可以稍微颠倒你的逻辑:

$.get('xmlfile.xml', function(xml) {
    var oXML = $(xml);

    oxml.find('user').each(function(i) {
        var index = i;
        $.getJSON($(this).attr('post'), function(res) {
            data[index].name = $(this).attr('name');
            data[index].pic = $(this).attr('pic');
            data[index].post = res;
        });
    });
});
于 2013-01-22T17:03:20.153 回答
1

主要问题getJSON是异步的

您的post属性datanull因为您在这里做错了两件事:

  1. getJSON.each是异步的,所以它在你已经执行后获取你的数据
  2. getJSON不返回数据而是jqXHR对象

尝试以这种方式更改它:

var data = []; // you likely want an array and not an object
var counter = 0;

$.get('xmlfile.xml', function(xml) {

    var oXML = $(xml);

    oxml.find('user').each(function(i) {
        var me = $(this);

        data.push({
            name: me.attr('name'),
            pic: me.attr('pic'),
            post: null
        });

        // increment counter
        counter++;

        $.getJSON(me.attr('post'), (function(index) {
            return function(data) {
                data[index].post = data;
                if (!--counter) // when it reaches ZERO
                {
                   setTimeout(function() {
                       // all JSONs have loaded now continue with your stuff
                   }, 0);
                }
            };
        })(i));
    });

});

上面的代码还检测所有 JOSN 对象何时已加载,以便您继续处理。

但除此之外,它以这种方式工作:

  1. 它获取 XML
  2. 当接收到 XML 时,它会遍历user元素并准备data对象并将它们推送到数组中
  3. 对于每个对象,它也会发出一个 Ajax 调用来获取 JSON 数据
  4. 每次成功调用 JSON 然后填充正确data对象的post属性并减少counter
  5. 当计数器达到零时,一个额外的函数正在排队,您可以在其中放置应该在所有内容加载并完成后执行的代码。

如果您的 JSON 请求也可能失败,那么我建议您使用$.ajax而不是getJSON这样您也可以提供error函数,其中您也将 decrement counter。否则,如果只计算成功,它就不会达到零。

于 2013-01-22T17:05:44.477 回答