for循环/递归中的执行顺序 [英] Sequence of execution in for loop / recursion

查看:132
本文介绍了for循环/递归中的执行顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是最近才了解jquery/javascript的,并且面临以下问题.

I only recently learned about jquery/javascript, and I am facing the following problem.

我正在尝试控制嵌套循环中的函数调用顺序和/或jquery/javascript中的递归.在我看来,现在几乎所有函数都被同时调用,并且不遵循我在其他编程语言(例如R)中惯用的顺序.在R脚本中,只要当前代码行未完成.但是似乎jquery代码正在同时触发我的所有getJSON请求,并在1个结果可用时立即处理结果.它不注意getJSON调用的顺序.这是真的,还是我错过了什么?在下面几次刷新页面会给我不同顺序的结果集,而一次又一次地期望相同的顺序...

I am trying to control the sequence of function calls in a nested loop and/or recursion in jquery/javascript. It seems to me now that all functions are called almost simultaneously and do not follow the order in the code as I am used to in other programming languages, such as R. In an R script the code will not process the next line as long as the current line of code is unfinished. But it seems that the jquery code is firing all my getJSON requests simultaneously, and processes the results as soon as 1 result becomes available. It does not pay attention to the order of the getJSON calls. Is this true, or am I missing something? Refreshing the page below a couple of time gives me result sets in different orders, whereas the same order would be expected, time after time...

为解释上述内容,我创建了以下可行的代码,该代码使用gridpointweather.com的api进行说明.

To explain the above I have created the following workable code, which uses the api of gridpointweather.com for illustration purposes.

<!DOCTYPE html>
<meta charset="utf-8">

<!--Body-->
<body>
    <div id="results"></div>
</body>

<!--Load jquery + uri.js-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/URI.js/1.17.0/URI.min.js"></script>

<script>
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // GLOBAL VARIABLES.
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    var g_asLoc =                         ["24", "42", "19"];
    var g_asWeather =                     [];

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    function getWeatherInfo(location, offset){    
        console.log("Location: " + location);
        console.log("Offset: " + offset);
        var sUrl = 'http://api.gridpointweather.com/weather/getjson?location=' + location + '%2C-72&model=gfs.api0.n7m4csjf3x2s92ic&hours=24&inunits=1&interptype=2&offset=' + offset;
        var requestUrl = sUrl;
        $.getJSON(requestUrl, function(data) {
            try {
                console.log("Data for location " + location, data);
            }catch(err) {
                console.log(err);
            }

            // Store something.
            $.each(data.data, function(index, weatherInfo){
                g_asWeather.push("Object " + index + ", Location: " + location + ", rawdate: " + weatherInfo.rawdate + ", Temp: " + weatherInfo.temp + "<br>");
            });

            // Offset with 25 if condition not met.
            if(offset == -25){
                // Display in #results.
                g_asWeather.push("<br><br>");
                $("#results").html(g_asWeather.join('\n'));
                console.log("Finished for location " + location);
                return;
            }else{
                console.log("Running again using offset " + (offset-25) + " for location " + location);
                getWeatherInfo(location, offset - 25);
            }
        }).error(function(){
                console.log("JSON error!");
                return;
        });
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // MAIN
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    var iCounter = 0;
    while(iCounter < 2){
        for(iLoc=0; iLoc<g_asLoc.length; iLoc++){
            getWeatherInfo(g_asLoc[iLoc], 0);
        }
        iCounter = iCounter + 1;
    }
</script>

最好,我希望代码为1个位置调用函数getWeatherInfo,然后在继续下一个位置之前完成该位置的递归...递归的顺序也很重要,因为offset = 0的结果应该在g_asWeather中,在offset = 25的结果之前.完成所有位置后,代码应等待1000 ms,然后再将iCounter加1,然后在iCounter<之前重复for循环. 2.要汇总结果集,应包含:iCounter = 0,位置24,偏移量= 0,偏移量= -25,位置42,偏移量= 0,偏移量= -25,位置19,偏移量= 0,偏移量= -25,等待1000ms,iCounter = 1,位置24,offset = 0,offset = -25等,而iCounter< 2.

Preferably I would want the code to call the function getWeatherInfo for 1 location, and then finish the recursion for this location before proceeding with the next location... The order of the recursion is also important, as results from offset=0 should be in g_asWeather, before the results of offset=25. After finishing all locations the code should wait, say 1000 ms, before increasing iCounter with 1 and repeat the for loop while iCounter < 2. To summarize the result set should contain: iCounter=0, location 24, offset=0, offset=-25, location 42, offset=0, offset=-25, location 19, offset=0, offset=-25, wait 1000ms, iCounter=1, location 24, offset=0, offset=-25 etc etc while iCounter < 2.

非常感谢.

推荐答案

是的,AJAX请求是异步的,因此您不知道每个请求以什么顺序结束.您可以做的是创建一个数组来保存信息,并使用for循环的索引对数据进行排序,例如,而不是这样做:

That's right, the AJAX requests are asynchronous so you don't know in which order is going to end each one. What you can do is create an array to save the information and use the index of the for loop to have the data ordered, for example, instead of doing this:

 g_asWeather.push("Object " + index + ", Location: " + location + ", rawdate: " + weatherInfo.rawdate + ", Temp: " + weatherInfo.temp + "<br>");

您可以执行类似的操作(将iLoc作为参数传递):

You could do something like that (passing the iLoc as parameter):

 g_asWeather[iLoc] = "Object " + index + ", Location: " + location + ", rawdate: " + weatherInfo.rawdate + ", Temp: " + weatherInfo.temp + "<br>");

因此,将按位置对数组进行排序,如果要以其他方式对数组进行排序,只需更改要存储字符串的变量即可.

So your array will be ordered by the location, if you want to order your array in some other way, just change the variable where it is going to be stored the string.

这篇关于for循环/递归中的执行顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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