5

As an example

var runInfinite = function(){
    while(1)
    {
       // Do stuff;
    }
};

setTimeout(runInfinite, 0);

Is it possible to break this runInfinite function form running infinite? I mean is it possible to kill this function from another function without using a flag or return statement?

7
  • 1
    Why do you rule out using a flag? Seems like the perfect place to use one. Commented Feb 14, 2013 at 8:30
  • 2
    AFAIK, the while(1) block will literally block the thread and not allow anything else to run. I don't have sources other than experience. (or maybe it just gets so slow that it comes to an effective freeze) If I had documentation, I'd post as an answer. Commented Feb 14, 2013 at 8:30
  • 1
    JavaScript (in browsers) is single threaded so the while loop actually blocks the thread; and you have no other thread which you could use to poll/set the flag. Commented Feb 14, 2013 at 8:34
  • @nunespascal lets think i have a stack of functions provided by users. I run them one after another. The problem is i can not ask users to put a flag inside their function. That's why I ruled out using a flag from my question. Commented Feb 14, 2013 at 8:36
  • 1
    @Somnath Sorry, mate, but in that case you are doomed. :) But seriously, you should not allow that. Scripts provided by users is a serious security issue. Commented Feb 14, 2013 at 8:37

6 Answers 6

5

The answer is no. Since JavaScript is single-threaded ( unless you are using some less common implementation which I doubt ) nothing can break a loop ( or any other block of code ) from outside.

Sign up to request clarification or add additional context in comments.

2 Comments

Well, if answer is NO. That means without "return" statement it is not possible. lets think if I inject if(isTimeoutFlag) return; inside user function at run time....thats may fix my issue? What you suggest?
It won't. Because then you would have to be able to set that flag to true which you can't do, because JavaScript is single-threaded ( unless you add this code to user's script, which you might find quite difficult ). :) I suggest not doing that at all - find another way without allowing users to write scripts.
2

There is no direct way to "kill" a running javascript function.

Possible workaround, although you need to replace the while(1) loop:

var i = 0; // for testing purposes

var toCall = "runInfinite()";
function runInfinite(){
    // do stuff
    console.log(i++);
    setTimeout(function(){ eval(toCall); }, 100); // or whatever timeout you want
}

setTimeout(function(){ eval(toCall); }, 0); // start the function
setTimeout(function(){ toCall = ""; }, 5000); // "kill" the function

I know using eval() is considered to be bad practice, however the idea should be clear. The function calls itself (not recursive, therefore the setTimeout()) using the toCall variable. Once this variable is unset, you kill it from outside.

You could wrap these variables and functions in a class so you can implement your "kill" function.

Comments

1

I've just tested on my browser.

AFAIK, the while(1) block will literally block the thread and not allow anything else to run. I don't have sources other than experience, but using the Chrome developer toolkit thing ctrl+shift+i typing while(1){} will block everything else due to the fact that browser-javascript is single threaded.

However, if you're using node.js, you may be able to as it has multithreading capabilities. If anyone is familiar enough with node.js and is willing to answer/edit, go for it. I've never quite used it.

5 Comments

Actually NodeJS is single-threaded as well ( and there is no multithreading capablitiy ) as it is built on V8 - the same JavaScript engine that is in Chrome.
stackoverflow.com/questions/5200821/… Apparently it can support multithreading-esque techniques though
Nope. The engine itself is using threads. But it does not mean that threads are available to a NodeJS programmer.
But it does mean that flags/sigkills should be able to be set/executed from another thread
Well, of course. You can always just kill the process from OS. :) But this cannot be done from inside JavaScript code.
1

The whay you want not really. But maybe you're doing it wrong. Try not to use while(1) if possible and at the end of the function call the function again if the outside flag triggered but some break button is not set, or return if otherwise

Comments

1

I admit this is not exactly the same, but, there are the Javascript generators and Javascript iterators in ECMA-262. If you can replace your function with a generator function, then, you can implement the breakable feature easily.

function execWithTimeout(iter, timeout = 100) {
    const limit = Date.now() + timeout
    for (const output of iter) {
        console.log(output)
        if (Date.now() > limit) throw(new Error("Timeout reached"))
    }
}

let runInfinite = function * () {
    let i = 0
    while (1) {
        yield i++
    }
}

execWithTimeout(runInfinite())

Comments

0

return can be used to stop a function from its current execution but not in your case.

In your case you could try to your function are wrapped in a try / catch block, you can find it out when your function gonna infinite ,based on that you can terminate its current execution.

2 Comments

lets think i have a stack of functions provided by users. I run them one after another. The problem is i can not ask users to put a flag inside their function. Are you saying me to inject code for time-out-rule inside users function?
I don't find any exception in the above function. How try /catch block is going to help? I'm confused!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.