获取多个XML文件时的AJAX回调

时间:2015-05-14 15:42:12

标签: javascript ajax xml callback

我正在努力更好地了解回调的工作原理。

在这个例子中,我想使用AJAX获取两个或更多XML文件,然后从中提取我需要的内容,然后将这些数据存储在AJAX调用之外的数组中。我想使用“dataExt”数组来绘制谷歌图表,但我正在挂断正确实现回调。我猜我的大脑还不够大!

这是我的代码段。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>

   // List of xml files.
   var xmlFeed = ['rss-feed1.xml', "rss-feed2.xml"];

  // An array to store each "dataString" from each XML file.
   var dataExt = [];

    for(var i = 0; i < xmlFeed.length; i++) {

        $.ajax({
        type: "GET",
        dataType: "xml",
        async: true,
        url: xmlFeed[i],
        contentType: "text/xml; charset=UTF-8",
        success: function(xml){

            var content = $(xml).find("content");
            var dataString = (content.text());
            console.log(dataString);

            // Need to push "dataString" to "dataExt" array.
            // dataExt = dataExt.push(dataString); <-- this doesn't work 

            }  

        }) // close ajax    
    } // close loop

    console.log(dataExt[0]);
    console.log(dataExt[1]);

</script>

2 个答案:

答案 0 :(得分:2)

当您发出AJAX请求时,对$ .ajax()的调用会立即返回。它不会等待内容通过网络返回。在您的示例中,在回调完成之前调用console.log()语句。

您想要的是一次回调,一旦获取了各种请求所需的所有数据,就会执行该回调。为此,您需要在您正在执行的各种AJAX调用之间进行某种同步。仅jQuery不支持这一点。

你可以自己动手。但是,这是一个足够普遍的设计问题,整个库都已经编写来处理它。

在Promise模式上做一些Google搜索。完成后,请查看Q库,这是该模式的几种实现之一。他们完成了为您同步多个AJAX请求的大部分艰苦工作。

示例:

function xmlPromise(name) {
    return Q.promise(function (resolve, reject, notify) {
        $.ajax({
            type: "GET",
            dataType: "xml",
            async: true,
            url: name,
            contentType: "text/xml; charset=UTF-8"
        })        
       .done(function (data) {
           resolve(data);
        }).fail(function () {
            reject();
        });
    });
};

var promises = [ xmlPromise('1.xml'), xmlPromise('2.xml') ];

var results = [];

Q.allSettled(promises).then(function(responses) {
    console.log(responses[0].value);
    console.log(responses[1].value);

    results.push(responses[0].value);
    results.push(responses[1].value);
});

在此示例中,xmlPromise()函数根据您要获取的URL为您创建一个promise对象。这个承诺代表了将在未来某个时间完成的工作单元。当你在promise中创建的AJAX调用成功返回时,它会调用resolve()方法,让Q知道已经履行了promise,并且数据已经可以使用了。

一旦构造了promise,我们将它们的数组传递给Q.allSettled(),它实际上会触发请求。因为这些请求是异步的,所以它们是并行执行的。一旦所有的promise都被解析或被拒绝,Q将调用你传递给then()方法的函数,并传入你的AJAX调用的结果。

答案 1 :(得分:0)

原始示例中的

在请求完成之前触发控制台日志。

希望这个例子是你的意思:

function getXml(file, successCallback){
    $.ajax({
        type: "GET",
        dataType: "xml",
        async: true,
        url: file,
        contentType: "text/xml; charset=UTF-8",
        success: successCallback

        }) // close ajax  
    }

    function sc(xml){
            var content = $(xml).find("content");
            var dataString = (content.text());
            console.log(dataString);

            // Need to push "dataString" to "dataExt" array.
            // dataExt = dataExt.push(dataString); <-- this doesn't work 

           // do whatever else you want next

    }

    pages ['1.xml', '2.xml'].forEach(function(v, i){
        getXml(v, sc);
    })