简体   繁体   中英

Stop an executing recursive javascript function

Using jQuery, I've build an image/slide rotator. The basic setup is (in pseudocode):

function setupUpSlide(SlideToStartWith){
    var thisSlide = SlideToStartWith;
    ...set things up...
    fadeInSlide(thisSlide)
}

function fadeInSlide(thisSlide){
    ...fade in this slide...
    fadeOutSlide(thisSlide)
}


function fadeOutSlide(thisSlide){
    ...fade out this slide...
    thisSlide.fadeOut(fade, function() {
    var timeout2 = setTimeout(setupUpSlide(nextSlide),100);
    }

I call the first function and pass in a particular slide index, and then it does its thing calling chain of functions which then, in turn, calls the first function again passing in the next index. This then repeats infinitely (resetting the index when it gets to the last item).

This works just fine.

What I want to do now is allow someone to over-ride the slide show by being able to click on a particular slide number. Therefore, if slide #8 is showing and I click #3, I want the recursion to stop and then call the initial function passing in slide #3, which then, in turn, will start the process again.

But I'm not sure how to go about that. How does one properly 'break' a recursive script. Should I create some sort of global 'watch' variable that if at any time is 'true' will return: false and allow the new function to execute?

UPDATE: Added more detailed code showing setTimeout call

Using recursion to implement a slideshow is probably not a good idea because it will eventually give a stack overflow .

Use timeouts instead.

setTimeout() - executes a code some time in the future

clearTimeout() - cancels the setTimeout()

Or intervals (thanks Ricket for pointing this out!):

The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds).

The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.

而不是间接递归,请尝试使用循环超时( var timer_id = setInterval(...) ),并在要停止它时使用clearTimeout

Here's an easy way to do it. First of all, instead of calling the functions directly, use window.setTimeout(function(){...}) at the end of each function, replacing the ... with the last line (that makes the recursive call). This will prevent the stack overflow.

Second, provide a way to communicate with the loop. Your boolean watch variable is a good idea. It doesn't have to be global, just something the function linked to your click handler and the slideshow functions both have access to--a static class variable, for instance. Watch that variable for changes and break the loop; or, have the variable be the currently set up slide.

Being easy, that doesn't mean this is the best way to do it. For one thing, your JQuery animation calls are asynchronous, and you need to be using their callback functions instead of the way you are doing it here, or all the animations are going to happen at once. You can do all of that in the space of one single function call in one function. JQuery allows chaining your animations, and it also allows you to issue a stop command to any existing animation. I would look into this way of doing it first instead of continuing with the setup you have now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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