JavaScript pausing execution of function to wait for user input

How do I make my main loop “pause” until an answer has been given by the player using the crane, and then proceed?

By breaking it up. The only “yield” in JavaScript on browsers is to let your function end and then arrange to get called back later (via setTimeout, setInterval, an ajax callback, etc.). In your case, I’d tend to think the trigger to call you back should be the user’s action answering the previous question, e.g., a click handler on the answer boxes or some such (rather than setTimeout and such, which are automated).

For instance, this code:

function loopArray(ar) {
    var index;
    for (index = 0; index < ar.length; ++index) {
       doSomething(ar[index]);
    }
}

…can be recast like this:

function loopArrayAsync(ar, callback) {
    var index;

    index = 0;
    loop();

    function loop() {
        if (index < ar.length) {
            doSomething(ar[index++]);
            setTimeout(loop, 0);
        }
        else {
            callback();
        }
    }
}

The second version yields control back to the browser on every loop iteration. It’s also important to note that the second version returns before the loops have been completed, whereas the first version waits until all loops are done, which is why the second version has the callback function it calls when it’s done looping.

Code calling the first one might look like this:

var a = ["one", "two", "three"];
loopArray(a);
// Code that expects the loop to be complete:
doTheNextThing();
doYetAnotherThing();

…whereas using the async version looks like this:

var a = ["one", "two", "three"];
loopArrayAsync(a, function() {
    // Code that expects the loop to be complete:
    doTheNextThing();
    doYetAnotherThing();
});

Doing this, you’ll probably find you use closures (loop, above, is a closure), and so this article may be useful: Closures are not complicated

Leave a Comment