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

How do I get a recursive function to output each return value, in javascript?

本文关键字:输出 返回值 递归函数 获取 javascript      更新时间:2023-09-26

所以我有这个函数

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这样你就可以实时看到字符串"演变"。我尝试使用这样的函数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;
}

但没有让它工作。有什么想法吗?

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

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

  • 调用generation并更新 DOM
  • 允许显示更新
  • 调用generation并更新 DOM
  • 允许显示更新
  • 等等...

因此,您需要从完成并允许显示更新的事件处理程序中调用它,而不是在循环中调用generationsetTimeout执行的代码正是适用于此的事件处理程序。但是,在您的情况下,setInterval功能确实是更好的选择。

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

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

所以,你最初有的地方:

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,它将停止运行它。

现在,

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;

看看这是否符合您的要求。

试试这个:

// 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。