javascript setTimeout 和递归函数执行流程

Posted

技术标签:

【中文标题】javascript setTimeout 和递归函数执行流程【英文标题】:java script setTimeout and recursive functions execution flow 【发布时间】:2018-03-11 14:13:36 【问题描述】:

我有一个如下的 javascript 函数。我想在 setTimeout 方法处暂停执行。据我所知,setTimeout 方法没有按预期工作,执行过程超出了 setTimeout 方法,并且在 100 秒后调用了 console.log("wait")。但这不是我所期望的,我想睡 100 秒。我将如何实现这一点,也可能是因为递归调用 console.log("wait") 只被调用一次,而不是所有递归调用。为什么?

function matrixSearch(array,row1,row2,col1,col2,value)
    
        console.log(array[row1][col1]);
        console.log(array[row2][col2]);
        if(value<array[row1][col1] || value > array[row2][col2])
            return false;
        if(value==array[row1][col1] || value == array[row2][col2])
            return true;
         var cRow1=row1,cCol1=col1,cRow2=row2,cCol2=col2;
         var midRow = Math.floor((row1+row2)/2);
         var midCol = Math.floor((col1+col2)/2);
         setTimeout(function() 
             console.log("wait");
         ,100);
         while((row1!=midRow || col1!=midCol) && (row2!=midRow || col2!=midCol))
         
            if(array[midRow][midCol]==value)
            
                return true;
            
            if (array[midRow][midCol]<value)
            
                row2=midRow;
                col2=midCol;
            
            else
            
                row1=midRow;
                col1=midCol;
            
            midRow = Math.floor((row1+row2)/2);
            midCol = Math.floor((col1+col2)/2);
         
         var found = matrixSearch(array,midRow+1,cCol1,cRow2,midCol,value);
         if(!found)
             found=matrixSearch(array,cRow1,midCol+1,midRow,cCol2,value);
         return found;
    

【问题讨论】:

【参考方案1】:

setTimeout 传递一个回调函数,该函数在给定时间后执行。下面的代码将在 setTimeout 行之后立即执行,而不是在指定的超时之后。

如果要让代码块在时间段后执行,需要放在回调函数中。

【讨论】:

但是我该如何实现睡眠。 Javascript 的行为与 Java/C 略有不同。您的超时基本上将传递的函数放入一个事件循环中,该循环一遍又一遍地传递,直到规定的时间过去。没有等同于睡眠的东西。【参考方案2】:

setTimeout 不是为了阻塞函数执行,它是为了延迟执行传递给 setTimeout 函数的回调函数,为了延迟函数的其余部分,你必须把它放在现在放置 console.log 的地方

【讨论】:

在这种情况下我应该如何阻止整个递归函数的执行。 我不记得在 es5 中有任何方法可以做到这一点,如果你可以使用更新的 js 版本你可以使用***.com/a/39914235/6671416【参考方案3】:

您需要将代码放入设置的超时时间以等待它,但这有点棘手,因为您的返回将不起作用

你可以对韭菜使用promise。我还没有测试过这段代码,所以它可能不会工作,但这是你需要采取的方向

function matrixSearch(array,row1,row2,col1,col2,value)
    
    return  new Promise(reslove,reject)
      setTimeout(function() 
        console.log(array[row1][col1]);
        console.log(array[row2][col2]);
        if(value<array[row1][col1] || value > array[row2][col2])
            return resolve(false);
        if(value==array[row1][col1] || value == array[row2][col2])
            return resolve(true);
         var cRow1=row1,cCol1=col1,cRow2=row2,cCol2=col2;
         var midRow = Math.floor((row1+row2)/2);
         var midCol = Math.floor((col1+col2)/2);
        
           while((row1!=midRow || col1!=midCol) && (row2!=midRow || col2!=midCol))
              
                if(array[midRow][midCol]==value)
                
                      return resolve(true);
                
                if (array[midRow][midCol]<value)
                
                    row2=midRow;
                    col2=midCol;
                
                else
                
                    row1=midRow;
                    col1=midCol;
                
                midRow = Math.floor((row1+row2)/2);
                midCol = Math.floor((col1+col2)/2);
              
              matrixSearch(array,midRow+1,cCol1,cRow2,midCol,value)
              .then(function(found) 
                if(found === false)
                   found = matrixSearch(array,cRow1,midCol+1,midRow,cCol2,value);
                  
              )
             
         ,100);
      
    

【讨论】:

【参考方案4】:

首先,setTimeout 使用毫秒,因此对于 100 秒的睡眠,您需要使用 100000 而不是 100

其次,setTimeout是异步的,这意味着回调函数被安排在设置的时间过去后执行,但其他代码仍在执行。

要做你想做的事,你需要一个虚拟变量和一个测试这个变量状态的while-loop条件:

proceed=false;
setTimeout('proceed=true;',100000);
while (!proceed) 
// rest of code

while 循环将保留代码直到 setTimeout proceed=true; 代码被执行。

【讨论】:

以上是关于javascript setTimeout 和递归函数执行流程的主要内容,如果未能解决你的问题,请参考以下文章

带有计时事件的 JavaScript 递归 (setTimeout)

JavaScript setTimeout 无递归无限循环

JavaScript中的递归异步函数

javascript 递归函数调用(recursive funciton call)

递归 setTimeout 使堆栈增长

这个javascript技巧是不是有C#对应物来避免过多的递归