如何确保递归函数在返回之前不会再次调用 [英] How to ensure a recursive function isn't called again before it returns

查看:138
本文介绍了如何确保递归函数在返回之前不会再次调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaScript和HTML5画布制作RPG。对于对话框,我添加了一个打字效果,好像NPC的对话框是自动输入的(逐个字母)。



当用户触发此功能时按下按钮。当函数通过string.length重复出现,在给定索引处附加每个字符时,我不希望用户能够再次按下该按钮,直到函数停止(到达字符串的结束索引)。



为此,我添加了 $(#responseButton)。prop('disabled',true); 函数重复出现, $(#responseButton)。prop('disabled',false); 当它的索引与对话框string.length匹配时。



问题:当函数重复出现时,似乎按预期禁用了按钮,但是一旦完成,我就可以继续点击启用按钮...每次按下按钮时,该函数似乎被调用了几次...即使先前调用的重复没有完成...这会导致文本被不断覆盖。



问题:如何确保在再次调用之前重复执行此功能?如果我一直点击按钮直到再次运行就会有延迟时间...

  typeEffect:function(index) {
if(index> = game.data.NPCdialog.length){
game.data.enableCycle = true;
$(#responseButton)。prop('disabled',false);
返回;
}
else {
$(#responseButton)。prop('disabled',true); //等到打字完成之后用户再次按下
$(#npc_dialog)。append(game.data.NPCdialog.charAt(index ++));
var t = setTimeout('Utilities.typeEffect('+(index)+')',40);
}
},


解决方案

Javascript是单线程的。除非你故意放弃控制,否则不能调用其他Javascript函数。



编辑



< Norgard写道:


肯定你看到了setTimeout,那里


我没有看到setTimeout并且不再叫我Shirley。



我认为他的计划会有效,除了几个事件排队处理程序被触发之前。



Growler,我认为你遇到的问题是你假设处理程序将被触发,并且按钮被禁用,单击,因此不会生成后续事件。我相信这不是正确的。



相反,试试这个:

  typeEffect:function(){
var enabled = true;

var process = function(index){
if(index> = game.data.NPCdialog.length){
game.data.enableCycle = true;
enabled = true;
$(#responseButton)。prop('disabled',false);
}
else {
$(#npc_dialog)。append(game.data.NPCdialog.charAt(index));
setTimeout(function(){
process(index + 1);
},40);
}
};

返回函数(索引){
if(enabled){
$(#responseButton)。prop('disabled',true);
进程(索引);
}
};
}(),


I'm making an RPG in JavaScript and HTML5 canvas. For the dialog, I added a "typing" effect to appear as if NPC's dialog is being typed out automatically (letter by letter).

This function is fired when a user presses a button. While the function recurs through the string.length, appending each character at the given index, I don't want the user to be able to press the button again until the function stops (reaches end index of string).

To do that, I've added $("#responseButton").prop('disabled', true); while the function is recurring, and $("#responseButton").prop('disabled', false); when it's index matches dialog string.length.

Problem: It seems that the button is disabled as expected while the function recurs, but as soon as it's done, I can keep clicking the enabled button... the function seems to be called several more times over each time the button is pressed... even if the recurrence from the previously called one hasn't finished... this results in the text being constantly overwritten.

Question: How do I ensure the function is done recurring before it can be called again? It's like there's a lag time if I keep clicking the button till when it runs again...

typeEffect : function (index) {     
    if (index >= game.data.NPCdialog.length) {
        game.data.enableCycle = true;
        $("#responseButton").prop('disabled', false);
        return;
    }
    else{
        $("#responseButton").prop('disabled', true); //wait until typing is done before user can press again
        $("#npc_dialog").append(game.data.NPCdialog.charAt(index++));
        var t = setTimeout('Utilities.typeEffect('+ (index) +')', 40);      
    }       
},

解决方案

Javascript is single-threaded. Unless you deliberately relinquish control, no other Javascript function can be called.

EDIT

Norgard writes:

surely you see the setTimeout, there

I didn't see the setTimeout and stop calling me Shirley.

And I think his plan would work, except that several events are queued up before the handler is fired.

Growler, I think the problem you are having is that you assume that the handler will be fired, and the button disabled, after the very first click and therefore no subsequent events could be generated. This is not, I believe, correct.

Instead, try this:

typeEffect : function() {
  var enabled = true;

  var process = function(index) {
    if (index >= game.data.NPCdialog.length) {
      game.data.enableCycle = true;
      enabled = true;
      $("#responseButton").prop('disabled', false);
    }
    else {
      $("#npc_dialog").append(game.data.NPCdialog.charAt(index));
      setTimeout(function() {
        process(index+1);
      }, 40);
    }
  };

  return function(index) {     
    if (enabled) {
      $("#responseButton").prop('disabled', true);
      process(index);
    }
  };
}(),

这篇关于如何确保递归函数在返回之前不会再次调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆