所以我有这个功能
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;
}
但没有让它发挥作用。有什么想法吗?
答案 0 :(得分:2)
您需要了解的第一件事是,在JavaScript完成之后,您在JavaScript中对HTML DOM所做的更改才会显示给用户(至少对于我所使用的所有主要浏览器都是如此)熟悉)。这意味着当您像循环一样更新循环中的DOM时,您将只看到最后一个值。
您使用setTimeout
接近正确的解决方案,但您的代码不正确,并且仍在循环中完成。你需要做的是这样的一系列步骤:
generation
并更新DOM generation
并更新DOM 因此,不是在循环中调用generation
,而是需要在完成的事件处理程序中调用它,并允许显示在再次调用之前更新。由setTimeout
执行的代码正是那种适用于此的事件处理程序。但是,在您的情况下,the setInterval
function确实是更好的选择。
setInterval
函数接受一个函数和一个延迟(以毫秒为单位)并重复调用该函数直到它被取消。
在您的情况下使用这些函数之一的棘手问题之一是您需要在调用之间维护状态(例如,score_met
和best_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。