JavaScript暂停执行功能等待用户输入

时间:2011-04-05 11:54:58

标签: javascript pausing-execution

我正在尝试使用HTML5画布,JavaScript和XML制作一种游戏。 我们的想法是,您可以通过将问题和答案放在XML文件中来进行测验。 我写了一个主循环,循环遍历所有问题,构建它们并检查答案的正确性。 现在我只是使用警报和对话框来回答问题 问题是我的主循环是一个大的互连整体,从头到尾遍历整个游戏,而不是让警报框提出问题和对话框来回答,紧接着,我想要一些用户互动。 问题的答案显示在屏幕底部的框中​​,用户可以控制起重机选择正确的答案。 这是我坚持使用的主循环代码片段:

answer = loadQuestion(i);
            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

            }

正如您所看到的,我正在调用loadQuestion,它会立即加载问题,显示可能的答案,现在立即抛出一个对话框,您可以在其中键入答案。 此答案将被返回并验证。

我已经编程了起重机的控制装置,用户已经可以拿起一个装有它的盒子。 但是因为我正在调用loadQuestion并期望它返回一个值,所以这不起作用。 如果玩家使用起重机给出答案,我该如何让我的主循环“暂停”,然后继续? 我已经尝试将答案作为一个全局变量,并且只需要一个空的而answer ==“”以保持函数忙于什么都不做,直到答案获得一个值,但这只是冻结了脚本。 我还试图监视应答变量的状态,并且在发生这种情况时清除间隔并返回值,但是这只是返回false,因为函数完成而没有立即返回值。

3 个答案:

答案 0 :(得分:19)

  

如果玩家使用起重机给出答案,我该如何让我的主循环“暂停”,然后继续?

分手吧。 JavaScript中浏览器中唯一的“收益”是让你的函数结束,然后安排稍后回调(通过setTimeoutsetInterval,ajax回调等)。在您的情况下,我倾向于认为触发回叫的触发器应该是用户回答上一个问题的操作,例如答案框上的click处理程序或其他一些(而不是setTimeout等等,这是自动化的。

例如,这段代码:

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

......可以像这样重铸:

function loopArrayAsync(ar, callback) {
    var index;

    index = 0;
    loop();

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

第二个版本在每次循环迭代时都会将控制权返回给浏览器。同样重要的是要注意第二个版本在 之前返回 完成循环,而第一个版本等待所有循环完成,这就是为什么第二个版本具有它完成循环后调用的callback函数。

调用第一个的代码可能如下所示:

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

...而使用异步版本看起来像这样:

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

这样做,你可能会发现你使用closuresloop,上面是一个闭包),所以这篇文章可能很有用:Closures are not complicated

答案 1 :(得分:3)

没有同步。除了alertconfirmprompt之外,在浏览器JS中暂停了输入/输出工具。由于您不想使用它们 - 请尝试以下模式:

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();
});

即。当用户回答它时 - 回调函数会被执行,你知道你很高兴。

答案 2 :(得分:2)

根据我的理解,你有一个问卷调查申请,你会问一系列问题,然后要求用户使用拖放控件(起重机)放弃他的答案。

我要去切线说设计似乎是错的。 Javascript是基于事件的,并且有一个主要线程循环用于用户交互将降低可用性。我不会使用任何方式来停止线程(也就是在java中)。 Javascript不是为这样的用例编写的。某些浏览器和几乎所有性能分析器(如Yslow)都会将您的应用程序视为无响应。

所以我会给每个问题提供一个由一个内部是序列(问题1 ... 2)的类标识的div。最初只会启用或显示一个问题。一旦用户回答了问题,我将启用已启用的问题。 (在适当的事件中,在这种情况下可能是拖放的下降事件)。由于它是顺序的,我只需检查用户是否已回答问题1,然后我将适当地启用问题2。整个流程应该是事件驱动的。这里的事件是用户回答问题。