多个AJAX调用以随机顺序返回JSON对象 [英] Multiple AJAX calls return JSON objects in random order

查看:93
本文介绍了多个AJAX调用以随机顺序返回JSON对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试存储返回的JSON对象

I'm trying to store the JSON objects returned like this

<div id="tabs-1" class="LIVE"></div>
<div id="tabs-2" class="past-matches"></div>
<div id="tabs-3" class="upcoming-matches"></div>    

使用以下脚本.

$(function() {
query=["select * from cricket.scorecard.live.summary","select * from      cricket.past_matches", "select * from cricket.upcoming_matches"]
container=[".LIVE",".past-matches",".upcoming-matches"]
container_no=0
query_no=0;
for( var section=0;section<query.length;section++)
{   
      $.ajax({
        url: "https://query.yahooapis.com/v1/public/yql",        
        jsonp: "callback",         
        dataType: "jsonp",        
        data: {
            q: query[query_no++],
            env:"store://0TxIGQMQbObzvU4Apia0V0",           
            format: "json"
        },       
        // Work with the response
        success: function(data ) {
             console.log( data ); // The problem: returns JSON objects in different order everytime the page reloads

             //I would like to store data like this
             if(container_no>0)
             {  
                if(container_no==1)
                {   $(container[container_no]).append('<p>recent match data</p>');
                    container_no++; 
                }
                else
                {
                    $(container[container_no]).append('<p>upcoming match data</p>');
                     container_no++; 
                }                   
            }   
            else{
               $(container[container_no]).append('<p>live match data</p>');
               container_no++;
            }
        }
    });
   }    
 });

问题在于,每次重新加载页面时,JSON对象都会以不同的顺序返回,因此我无法将数据保存在正确的div中.我认为我犯了一个涉及可变范围的错误. 这是小提琴: FIDDLE

The problem is JSON objects are returned in different order every time the page is reloaded, so I can't save the data in the right div. I think I made a mistake involving variable scope. here's the fiddle:FIDDLE

推荐答案

Ajax调用是异步的(这就是Ajax中"A"的含义).因此,它们有不确定的执行时间,并且当您执行多个Ajax调用时,无法保证结果将到达的顺序.

Ajax calls are asynchronous (that's what the "A" stands for in Ajax). Thus, they have an indeterminate time to execute and when you execute multiple Ajax calls, there is no guaranteed order that the results will arrive.

因此,如果您想知道哪个结果是哪个(例如,哪个是第一个,第二个,依此类推),则必须创建一个计数器,该计数器对于每个ajax调用都是唯一的.一种方法是将每个Ajax调用放入一个函数调用中,然后将一个计数器传递到该函数调用中.该函数将创建一个关闭操作,结果返回时将为您维护计数器.

So, if you want to know which result is which (e.g. which is the first, the second and so on), you have to create a counter which is unique for each ajax call. One way to do that is to put each Ajax call into a function call and pass a counter into that function call. This function will create a closure and the counter will be maintained for you when the results come back.

这是一个使用函数的版本,该函数来自使用.forEach()来迭代查询数组.我还做了其他一些修改以简化代码:

Here's a version using a function that comes from using .forEach() to iterate your query array. I've also made several other modifications to simplify the code:

$(function() {
    var query = ["select * from cricket.scorecard.live.summary", "select * from      cricket.past_matches", "select * from cricket.upcoming_matches"];
    var container = [".LIVE", ".past-matches", ".upcoming-matches"];
    var msg = ['<p>live match data</p>', '<p>recent match data</p>', '<p>upcoming match data</p>'];
    query.forEach(function(queryVal, cnt) {
        $.ajax({
            url: "https://query.yahooapis.com/v1/public/yql",
            jsonp: "callback",
            dataType: "jsonp",
            data: {
                q: queryVal,
                env: "store://0TxIGQMQbObzvU4Apia0V0",
                format: "json"
            },
            // Work with the response
            success: function(data) {
                console.log(data);
                $(container[cnt]).append(msg[cnt]);
            }
        });
    }
});

这是创建IIFE(立即调用的函数表达式)以解决相同问题的另一个版本:

Here's another version that creates an IIFE (immediately invoked function expression) to solve the same problem:

$(function() {
    var query = ["select * from cricket.scorecard.live.summary", "select * from      cricket.past_matches", "select * from cricket.upcoming_matches"];
    var container = [".LIVE", ".past-matches", ".upcoming-matches"];
    for (var section = 0; section < query.length; section++) {
        // add IIFE so we can capture the section number uniquely for each ajax call
        (function(cnt) {
            $.ajax({
                url: "https://query.yahooapis.com/v1/public/yql",
                jsonp: "callback",
                dataType: "jsonp",
                data: {
                    q: query[cnt],
                    env: "store://0TxIGQMQbObzvU4Apia0V0",
                    format: "json"
                },
                // Work with the response
                success: function(data) {
                    console.log(data);

                    var msg;
                    if (cnt === 0) {
                        msg = '<p>live match data</p>'
                    } else if (cnt === 1) {
                        msg = '<p>recent match data</p>';
                    } else {
                        msg = '<p>upcoming match data</p>';
                    }
                    $(container[cnt]).append(msg);
                }
            });
        })(section);
    }
});

注意,我还为所有局部变量添加了var,这样就不会意外创建全局变量.

Note, I also added var to all your local variables so you are not accidentally created global variables.

如果您实际上要等到所有结果都收集完后再按循环顺序添加它们,则可以使用jQuery的$.when()来完成.

If you actually want to wait until ALL results are collected so you can then add them exactly in your loop order, then you can use jQuery's $.when() to do that.

$(function() {
    var query = ["select * from cricket.scorecard.live.summary", "select * from      cricket.past_matches", "select * from cricket.upcoming_matches"];
    var container = [".LIVE", ".past-matches", ".upcoming-matches"];
    var msg = ['<p>live match data</p>', '<p>recent match data</p>', '<p>upcoming match data</p>'];
    var promises = [];
    query.forEach(function(queryVal, cnt) {
        promises.push($.ajax({
            url: "https://query.yahooapis.com/v1/public/yql",
            jsonp: "callback",
            dataType: "jsonp",
            data: {
                q: queryVal,
                env: "store://0TxIGQMQbObzvU4Apia0V0",
                format: "json"
            },
        }));
    }
    // wait for all ajax results to be done
    $.when.apply($, promises).then(function() {
        for (var i = 0; i < arguments.length; i++) {
            // iterate all results in order
            console.log(arguments[i][0]);
        }
    });
});

这篇关于多个AJAX调用以随机顺序返回JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆