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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Somnath
  • 3,247
  • 4
  • 28
  • 42
  • 1
    Why do you rule out using a flag? Seems like the perfect place to use one. – nunespascal Feb 14 '13 at 08: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. – Snakes and Coffee Feb 14 '13 at 08: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. – Salman A Feb 14 '13 at 08: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. – Somnath Feb 14 '13 at 08: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. – freakish Feb 14 '13 at 08:37
  • @freakish cool. :) but I'm sure that users are not going to write while(true){} in their code. But think like some process going on which takes time to complete. And cancel request comes to me. And i need to cancel all process present in my stack! – Somnath Feb 14 '13 at 08:43
  • @Somnath You should not assume that users won't write such loop. Forget about hackers, most users are simply, er, you know, stupid. :) And about hackers: do you know how much info they can steal ( and do more serious damage ) with such awesome security hole? – freakish Feb 14 '13 at 08:50

6 Answers6

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.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • 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? – Somnath Feb 14 '13 at 08:49
  • 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. – freakish Feb 14 '13 at 08:51
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.

Uooo
  • 6,204
  • 8
  • 36
  • 63
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.

Snakes and Coffee
  • 8,747
  • 4
  • 40
  • 60
  • 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. – freakish Feb 14 '13 at 08:39
  • http://stackoverflow.com/questions/5200821/grasping-the-node-js-alternative-to-multithreading Apparently it can support multithreading-esque techniques though – Snakes and Coffee Feb 14 '13 at 08:41
  • 1
    Nope. The engine itself is using threads. But it does not mean that threads are available to a NodeJS programmer. – freakish Feb 14 '13 at 08:43
  • But it does mean that flags/sigkills should be able to be set/executed from another thread – Snakes and Coffee Feb 14 '13 at 08:44
  • Well, of course. You can always just kill the process from OS. :) But this cannot be done from inside JavaScript code. – freakish Feb 14 '13 at 08:48
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

TheBrain
  • 5,528
  • 2
  • 25
  • 26
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())
Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
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.

Community
  • 1
  • 1
arvin_codeHunk
  • 2,328
  • 8
  • 32
  • 47
  • 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? – Somnath Feb 14 '13 at 08:40
  • I don't find any exception in the above function. How try /catch block is going to help? I'm confused! – Somnath Feb 14 '13 at 08:54