如何在javascript中获取输出每个返回值的递归函数?

时间:2016-03-15 18:08:42

标签: javascript

所以我有这个功能

function main()
{
    //get the start text
    var start_text = document.getElementById("start_text").value;

    //get target text
    var target_text = document.getElementById("target_text").value;

    // get characters to use for modifying string
    var characters = document.getElementById("characters").value;

    // get the mutation rate
    var mutation_rate = document.getElementById("mutation_rate").value;

    // get the amount of offspring for each generation
    var amount_offspring =     document.getElementById("amount_offspring").value;

    // send all the input into generation, to generate a generation of offspring.
    // this function will return the highest scoring offspring of each generation
    best_offspring = generation(start_text, characters, amount_offspring, mutation_rate, target_text, generations);

    // keep looping untill the target_text is met
    while(score_met == false)
    {
        //send the highest scoring offspring again
        best_offspring = generation(best_offspring, characters, amount_offspring, mutation_rate, target_text);
        // output the best offspring
        document.getElementById("output_text").value = best_offspring;
        // output the amount of generations
        document.getElementById("generations").value = generations;
    }
}

一切都有效,除了它在while循环完成时输出完成的字符串。

我想要的是输出每一代best_offspring,以便您可以看到字符串" evolve"实时。我尝试使用函数setTimout(),如:

    while(score_met == false)
{
    //send the highest scoring offspring again
    best_offspring = setTimeout(generation(), 1000, best_offspring, characters, amount_offspring, mutation_rate, target_text);
    document.getElementById("output_text").value = best_offspring;
    document.getElementById("generations").value = generations;
}

但没有让它发挥作用。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

您需要了解的第一件事是,在JavaScript完成之后,您在JavaScript中对HTML DOM所做的更改才会显示给用户(至少对于我所使用的所有主要浏览器都是如此)熟悉)。这意味着当您像循环一样更新循环中的DOM时,您将只看到最后一个值。

您使用setTimeout接近正确的解决方案,但您的代码不正确,并且仍在循环中完成。你需要做的是这样的一系列步骤:

  • 致电generation并更新DOM
  • 允许显示更新
  • 致电generation并更新DOM
  • 允许显示更新
  • 等......

因此,不是在循环中调用generation,而是需要在完成的事件处理程序中调用它,并允许显示在再次调用之前更新。由setTimeout执行的代码正是那种适用于此的事件处理程序。但是,在您的情况下,the setInterval function确实是更好的选择。

setInterval函数接受一个函数和一个延迟(以毫秒为单位)并重复调用该函数直到它被取消。

在您的情况下使用这些函数之一的棘手问题之一是您需要在调用之间维护状态(例如,score_metbest_offspring变量)。现在我建议您使用全局变量,因为它是最简单的,但更好的解决方案是使用closure

所以,你最初的地方:

while(score_met == false)
{
    best_offspring = generation(best_offspring, characters, amount_offspring, mutation_rate, target_text);
    document.getElementById("output_text").value = best_offspring;
    document.getElementById("generations").value = generations;
}

您可以将其替换为:

var interval = setInterval(function () {
    best_offspring = generation(best_offspring, characters, amount_offspring, mutation_rate, target_text);
    document.getElementById("output_text").value = best_offspring;
    document.getElementById("generations").value = generations;
    if (score_met) {
        clearInterval(interval);
    }
}, 1000); // runs every second

这将每秒运行一次generation函数,并在每次运行时更新DOM。 score_met变量设置为true后,它将停止运行。

答案 1 :(得分:0)

现在,在while循环的每次迭代中,您使用=运算符将输出文本的值设置为当前的best_offspring。

听起来你想要做的就是追加当前的best_offspring。这可以使用+=运算符完成。

尝试替换

// output the best offspring
document.getElementById("output_text").value = best_offspring;

使用:

// output the best offspring
document.getElementById("output_text").value += best_offspring;

看看那是否符合你的要求。

答案 2 :(得分:0)

试试这个:

// this will set the Interval to run in the event queue, but gives the UI a chance to get updated
var loopId = setInterval(function() {
    //send the highest scoring offspring again
    best_offspring = generation(best_offspring, characters, amount_offspring, mutation_rate, target_text);
    document.getElementById("output_text").value = best_offspring;
    document.getElementById("generations").value = generations;
    if (score_met == false) {
        // this clears the loop when the condition is net
        clearInterval(loopId);
    }
}, 0);  // zero should be enough to update the display

这是我在页面上做的一个例子:

var loopId = setInterval(function() {
    var x = Math.floor(Math.random() * 1000) + 1;
    $('#someInputId').val(x);
    if (x === 1000) {
        clearInterval(loopId);
    }
}, 0);

它在输入框中显示一堆随机数,直到该值为1000。