简体   繁体   English

如何使用Jquery / javascript将递归函数转换为循环函数

[英]How to convert a recursive function to a looped function with Jquery/javascript

I'm trying to make a slideshow using Jquery, the pictures are cycled by a function that calls itself every 5.5 seconds. 我正在尝试使用Jquery进行幻灯片显示,图片由每5.5秒调用一次的函数循环播放。 However, I'm trying to avoid recursion since it is very expensive comparing to iterative calls. 但是,我试图避免递归,因为与迭代调用相比,它非常昂贵。 And I'm assuming that is the cause for IE to have a non-stopping loading icon when my slideshow is loaded. 而且我认为这是导致IE在加载幻灯片时出现不间断加载图标的原因。 So I want to convert the following function to an iterative one. 因此,我想将以下函数转换为迭代函数。

function playslides()
{

//hide previous slide
$(document.getElementById(t)).fadeOut("slow");


//reset slide index
calcSildes();

//show new slide
$(document.getElementById(t)).fadeIn("slow");

//recursive call after 5.5 sec
timer = setTimeout("playslides()", 5500);

}


//on page load...

$(document).ready(

playslides();

);

so far my two approaches are: 到目前为止,我的两种方法是:

  1. create a while loop inside the $(document).ready() function and loop playslides() function. 在$(document).ready()函数内创建一个while循环,并循环playlides()函数。

  2. create another timer function that calls the playslides() function, and let playslides function call that timer function. 创建另一个调用playslides()函数的计时器函数,然后让playslides函数调用该计时器函数。 (Not sure if this avoids recursion at all...) (不确定是否完全避免递归...)

Thanks!! 谢谢!!

Sounds like you should replace setTimeout() with setInterval() , which will simply repeat the given function until its canceled. 听起来您应该将setTimeout()替换为setInterval() ,它将简单地重复给定的函数直到其被取消。 No recursion or looping necessary. 无需递归或循环。

Quoting John Resig , creator of jQuery: 引用 jQuery的创建者John Resig

At a fundamental level it's important to understand how JavaScript timers work. 从根本上讲,了解JavaScript计时器的工作原理很重要。 Often times they behave unintuitively because of the single thread which they are in. Let's start by examining the three functions to which we have access that can construct and manipulate timers. 通常,由于它们位于单个线程中,因此它们的行为不直观。让我们从检查可以构造和操纵计时器的三个函数开始。

var id = setTimeout(fn, delay); - Initiates a single timer which will call the specified function after the delay. -启动单个计时器,该计时器将在延迟后调用指定的函数。 The function returns a unique ID with which the timer can be canceled at a later time. 该函数返回一个唯一的ID,以后可以使用该ID取消计时器。

var id = setInterval(fn, delay); - Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled. -与setTimeout相似,但是会连续调用该函数(每次都有延迟),直到取消该函数为止。

clearInterval(id); , clearTimeout(id); clearTimeout(id); - Accepts a timer ID (returned by either of the aforementioned functions) and stops the timer callback from occurring. -接受计时器ID(由上述任一功能返回),并停止发生计时器回调。

Using setInterval , you could simplify your code to the following: 使用setInterval ,可以将代码简化为以下内容:

function playslides()
{
    //hide previous slide
    $(document.getElementById(t)).fadeOut("slow");

    //reset slide index
    calcSildes();

    //show new slide
    $(document.getElementById(t)).fadeIn("slow");
}

$(document).ready(function() {
     setInterval(playslides, 5500);
});

https://developer.mozilla.org/en/window.setInterval

var intervalID = window.setInterval(playslides, 5500);

You can't create a loop with delayed iterations. 您无法创建具有延迟迭代的循环。

The only optimization is replacing "playslides()" with playslides , and caching the jQuery objects which refer to the same object: 唯一的优化正在取代"playslides()"playslides ,并缓存该指代相同的对象jQuery的对象:

var timer;
function playslides($element) {
    //hide previous slide
    $element.fadeOut("slow");

    //reset slide index
    calcSildes();

    //show new slide
    $element.fadeIn("slow");

    //recursive call after 5.5 sec
    timer = setTimeout(playslides, 5500, $element);
}

// Bug fix too, wrap document.ready in `function(){
$(document).ready(function(){
    playslides($("#"+t));    
});

This is not a recursive function. 这不是递归函数。 A recursive function continues to create and retain copies of itself in memory until the base case is reached, after which, the stack unwinds and values are returned. 递归函数将继续创建其自身的副本并将其副本保留在内存中,直到达到基本情况为止,此后,堆栈将展开并返回值。 There must also be a change to the parameters in the recursive call which will eventually lead to the base case. 还必须更改递归调用中的参数,这最终将导致基本情况。

PHP Example: PHP示例:

function recursive_function($num){
    if ($num == 0){ //base case
        return 10;
    }else{
        return $num + recursive_function($num-1);
    }
}

recursive_function(5);//output is 25

Your function is just creating new timers which call the same function after the original has left memory. 您的函数只是创建新的计时器,这些计时器会在原始内存离开后调用相同的函数。

Remove the 'timer = setTimeout(playslides, 5500, $element);' 删除“ timer = setTimeout(playslides,5500,$ element);” line in the playslides function. 行中的幻灯片。

Replace the 'playslides($("#"+t));' 替换为'playslides($(“#” + t));' call in the document.ready function with: 使用以下命令调用document.ready函数:

timer = window.setInterval(function(){
    playslides($("#"+t));
}, 5500);

You need to create an anonymous function for setinterval to properly pass parameters (for older browsers...not in HTML5). 您需要为setinterval创建一个匿名函数以正确传递参数(对于较旧的浏览器...不适用于HTML5)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM