Javascript - 在递归函数中获取 setTimeout 的返回值

Posted

技术标签:

【中文标题】Javascript - 在递归函数中获取 setTimeout 的返回值【英文标题】:Javascript - getting return value for setTimeout in recursive function 【发布时间】:2012-02-09 04:46:55 【问题描述】:

我有一个递归函数,其中包含一些绘图代码。我被建议使用 setTimeout,因为我的绘图直到执行结束才显示。首先我将绘图代码放在 setTimeout 中,但这并没有帮助,但是当我将主递归循环放在 setTimeout 中时,绘图工作得很好,如下所示。

但是我需要使用 setTimeout 的返回值(即state,如下图所示)。如何在使用setTimeout的时候得到这个返回值,或者用别的方法解决这个问题。

var doLearning = function(time, observedData, state, domain, sampleAction, selectModel, numSamples, depth, discount, stateQueries) 
    if(stateQueries[0](time, state) === true) 
        console.log("New Round");
        var currentModel = selectModel(observedData, 10, stateQueries);
        var bestAction = sparseSampleMcmc(depth, numSamples, discount, currentModel, state, sampleAction, stateQueries);
        var newStateReward = domain.executeAction(bestAction, stateQueries);
        observedData.push(bestAction, newStateReward[1], newStateReward[0]);
        console.log(time);
        setTimeout(doLearning, 100, time + 1, observedData, newStateReward[0], domain, sampleAction, selectModel, numSamples, depth, discount, stateQueries);
     else 
        console.log("Game Over");
        return state;
    

【问题讨论】:

你能解释一下为什么你需要那个值吗?它可能有助于我们提供适当的答案。 递归是对doLearning的调用。我需要这个值,因为 selectModel 实际上也调用了 doLearning。它返回我在以下步骤中使用的模型,例如选择 bestAction 【参考方案1】:

使用所有变量创建一个对象,例如:

var game = 
     time: ... ,
     observedData: ...., 
     state: .... etc
 

doLearning 中获取并在必要时修改此对象的属性:

  var doLearning = function(obj) 

       if(obj.state == ....)
           obj.currentModel = whatever...
           obj.bestAction = whatever...
           setTimeout(function()  doLearning(obj) , 100)
       else
           game over
  

【讨论】:

【参考方案2】:

这让我有话要说,但是如果你有一个全局变量,返回值会去哪里呢?在doLearning结束时设置,然后当检测到超时/绘图完成时,检查全局。

【讨论】:

不必是全球性的——只是在doLearning的范围之外。【参考方案3】:

如果没有所有代码,我很难理解,但使用setInterval 可能会更好,这是一个简单的示例。

function draw()
  var state=//whatever
  var num = setInerval(doLearning,100)  

  function doLearning()
    //You have access and can modify state and do not need to return its value
    if()
    else
      clearInterval(num);
      console.log('Game over');
    
  

【讨论】:

【参考方案4】:

通过如下调用,当前执行上下文(即当前doLearning实例的环境)形成一个闭包,其中time,observedData等仍然可用于setTimeout() 语句中定义的匿名函数。

因此,以下应该可以工作:

setTimeout(function()
    doLearning(time + 1, observedData, newStateReward[0], domain, sampleAction, selectModel, numSamples, depth, discount, stateQueries);
, 100);

【讨论】:

以上是关于Javascript - 在递归函数中获取 setTimeout 的返回值的主要内容,如果未能解决你的问题,请参考以下文章

递归打印字符串的所有排列(Javascript)

javascript --- 递归的简单理解

JavaScript函数之递归

递归 JavaScript 函数正在丢失返回值

JavaScript学习(七十四)—递归函数

如何利用JavaScript语言获取Map集合中元素个数