JavaScript pausing execution of function to wait for user input

老子叫甜甜 提交于 2019-11-28 07:44:55

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

There is no sync. paused input/output tools in browser JS except of alert, confirm and prompt. Since you don't want to use those - try the following pattern:

loadQuestion(i, function(answer) {
   if (answer == "correct") {
            // answered correctly, update scoreArray and load next question
            scoreArray[currentQuestion] = "correct";
            // show 'next'-button and wait for press to continue

        } else {
            // answered incorrectly again, update scoreArray and load next question
            scoreArray[currentQuestion] = "error";
            // show 'next'-button and wait for press to continue

        }
  resumeGameExecution();
});

I.e. when user answers it - the callback function gets executed and you know that you're good to go.

From what I understand you have a questionnaire application, where you ask a series of questions and then ask the user to drop his answer using some drag and drop control ( a crane).

I am going to go an a tangent and say the design seems to be wrong. Javascript is event based and having one main thread looping around for user interaction is going to reduce the usability. I will not use any way of stalling the thread ( aka in java). Javascript is not written for such an usecase. Your application will be perceived as non responsive by some browsers and by almost all performance analyzers (like Yslow).

So I would provide each question with a div identified by a class which internally is a sequence (question1..2). Initially only one question will be enabled or visible. Once user answers the question, I will enable the enabled question. ( on the appropriate event, in this case probably the drop event of drag and drop). Since it is sequential, I will just have to check if the user has answered question1, then I will enable question2 appropriately. The whole flow should be event driven. The event here being the user answering the question.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!