【问题标题】:js setTimeout recursion return-continuejs setTimeout递归返回-继续
【发布时间】:2012-05-26 12:39:22
【问题描述】:

我将使用这个用 C 编写的简单的迷宫解算程序来举例说明我在 javascript 中需要什么:

int is_free_place(int x,int y) {
 char ch[2];
 if(x<1||x>80||y<1||y>20)
  return 0;
 gettext(x,y,x,y,ch);
 return ch[0]==32; // X or space
}
int solve(int x, int y, int x_end,int y_end) {
 int ans=0;
 if(kbhit()) efn();
 gotoxy(x,y);
 putchar('.');
 delay(DELAY_TIME);
 if(x==x_end&&y==y_end)
  return 1;
 if(is_free_place(x-1,y))
  ans=solve(x-1,y,x_end,y_end);      //// <<<<< recursion starts here
 if(ans==0&&is_free_place(x+1,y))    //// can't continue to here if using setTimeout
  ans=solve(x+1,y,x_end,y_end);      //// because ans is not set
 if(ans==0&&is_free_place(x,y-1))
  ans=solve(x,y-1,x_end,y_end);
 if(ans==0&&is_free_place(x,y+1))
  ans=solve(x,y+1,x_end,y_end);
 if(ans==0){
  gotoxy(x,y);
  putchar(' ');
  delay(DELAY_TIME);
 }
 return ans;
}
void main(){
 clrscr();
 efn(); // reads maze from file, shows menu, calls solve()
}

我正在尝试在 javascript 中进行类似的递归,但浏览器会冻结,直到代码完成,我需要的是一个缓慢的进度动画,可以选择暂停和更改内容。所以我尝试使用setTimeout,但我无法弄清楚函数何时“返回”并且代码从递归调用继续的算法...... (setTimeout 立即继续,不等待函数返回)

[更新] 有没有办法使用yield而不是使用堆栈来做到这一点?

【问题讨论】:

  • 我们不会为你编写所有的 JS。向我们展示你所拥有的(希望比 C 版本更具可读性)。
  • 我不需要JS中的所有C代码;)我只需要返回部分的想法(我知道setTimeout返回id,我说的是setTimeout函数的返回电话)所以我可以做一个不同的,更大的项目......

标签: javascript c++ recursion return settimeout


【解决方案1】:

setTimeout 只运行一次。它的返回值就是超时本身。

var timeout = setTimeout(function () { console.log( "hi" ) }, 1000);
// timeout == some id

如果您选择使用clearTimeout 方法清除超时,这允许您清除超时

您可以使用递归setTimeout 循环来创建游戏循环。

setTimeout(function call() {
     // Do code
     //...     
     setTimeout( call, 1000 / 60 ); // loop
}, 1000 / 60 ) // 60 fps

【讨论】:

    【解决方案2】:

    这是一个 javascript 示例,如何使用 setTimeout 以及如何使用 clearTimeout 清除它。

    <html>
    <head>
    <script type="text/javascript">
    var c=0;
    var t;
    var timer_is_on=0;
    
    function timedCount()
      {
      document.getElementById('txt').value=c;
      c=c+1;
      t=setTimeout("timedCount()",1000);
      }
    
    function doTimer()
      {
      if (!timer_is_on)
        {
        timer_is_on=1;
        timedCount();
        }
      }
    
    function stopCount()
      {
      clearTimeout(t);
      timer_is_on=0;
      }
    </script>
    </head>
    <body>
    
    <form>
    <input type="button" value="Start count!" onclick="doTimer()" />
    <input type="text" id="txt" />
    <input type="button" value="Stop count!" onclick="stopCount()" />
    </form>
    
    </body>
    </html>
    

    取自here.

    【讨论】:

    • 那么,我知道这一切,但这不是我需要的。我需要处理 setTimeout 内的函数的返回...
    • @Antonimo 你不能从传递给setTimeout 的回调中返回任何东西(无论如何都是有用的)。
    • @MattBall 对,这就是为什么我试图想出一个解决方法来获得我给出的示例 C 代码的类似结果。
    【解决方案3】:

    我认为 setInterval 可以胜任:setInterval

      var int = setInterval(clock,1000);
    
      function clock()
      {
         var d=new Date();
         var t=d.toLocaleTimeString();
         document.getElementById("clock").value=t;
      }
    

    【讨论】:

    • 这是一个循环,不是递归
    【解决方案4】:

    把它写成你可以与 setTimeout 一起使用的东西会有点不平凡,特别是因为正如所写的那样,你需要得到你的递归调用的结果。我认为处理此类事情的最简单方法是必须使用某种 Promise 基础设施,如 dojo 和 jQuery(或自己编写)。我会更详细地介绍,但目前我无法进一步处理。一个提示:我认为 jQuery 的 pipe 方法会在这里创造奇迹。

    想到的其他选择是重写它以使用一个堆栈来保存 ans 变量,并且可能表示您需要返回到当前函数调用的哪一部分。

    【讨论】:

    • 我想出的“混乱”解决方案确实是使用堆栈,我在调用 setTimeout 之前向其中添加局部变量,并将函数划分为“步骤”。它适用于迷宫求解器,但是继续使用这种方法太混乱了,我需要真正的递归 =)
    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 2022-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 2016-04-25
    相关资源
    最近更新 更多