【问题标题】:Javascript - getting return value for setTimeout in recursive functionJavascript - 在递归函数中获取 setTimeout 的返回值
【发布时间】: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

标签: javascript recursion return settimeout


【解决方案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);
      

      【讨论】:

        猜你喜欢
        • 2011-12-31
        • 2017-09-24
        • 1970-01-01
        • 1970-01-01
        • 2012-05-29
        • 2013-03-18
        • 1970-01-01
        • 2022-11-05
        相关资源
        最近更新 更多