我有以下课程:
// Population class
class Population {
constructor(size, target, mutationRate, minFitness) {
this.target = target;
this.size = size;
this.individuals = [];
// contains phrases (strings)
this.matePool = [];
this.mutationRate = mutationRate;
this.bestFitness = 0;
this.bestPhrase = "";
this.totalGenerations = 0;
// Stopping criterion
this.minFitness = minFitness;
}
clearMatePool () {
this.matePool = [];
}
addIndividual(newIndividual) {
this.individuals.push(newIndividual);
}
evaluate() {
let fitness = 0;
for (let i = 0; i < this.size; i++) {
fitness = this.individuals[i].fitnessFunct(this.target);
// Update best fitness and best phrase
if (fitness > this.bestFitness) {
this.bestFitness = fitness;
this.bestPhrase = this.individuals[i].getGenotype();
}
}
// Stopping criterion
if (this.bestFitness < this.minFitness) {
return true;
}
else {
return false;
}
}
buildMatePool() {
for (let i = 0; i < this.size; i++) {
let n = Math.round(this.individuals[i].getFitness() * 100);
for (let j = 0; j < n; j++) {
this.matePool.push(this.individuals[i].phrase);
}
}
}
reproduce() {
// Create new generation
for (let i = 0; i < this.size; i++) {
// Pick 2 parents
let a, b, child, midpoint;
while (true) {
// Index of parentA
a = getRandomIntInclusive(0, this.matePool.length - 1);
// Index of parentB
b = getRandomIntInclusive(0, this.matePool.length - 1);
// Be sure you have picked two unique parents (phrases)
if (this.matePool[a] === this.matePool[b]) {
continue;
}
else {
break;
}
}
// Crossover
child = this.crossover(a, b);
// Mutation
this.mutation(child);
// The new child is part of the new population
this.individuals[i] = child;
}
this.totalGenerations += 1;
}
crossover(a, b) {
let child = new Individual(this.target.length);
child.setGenotype("");
let midpoint = getRandomIntInclusive(0, this.target.length-1);
for (let i = 0; i < this.target.length; i++) {
if (i < midpoint) {
child.phrase = child.phrase + this.matePool[a].charAt(i);
}
else {
child.phrase = child.phrase + this.matePool[b].charAt(i);
}
}
return child;
}
mutation(individual) {
for (let i = 0; i < this.target.length; i++) {
// The block inside the conditional statement would be executed 1% of the time.
if(Math.random() < this.mutationRate) {
// replace char with a new random character
individual.phrase = individual.phrase.substr(0, i) + String.fromCharCode(getRandomIntInclusive(32, 128)) + individual.phrase.substr(i + 1);
}
}
}
}
我有以下DOM元素:
// Shows the current generation
var totalGenerationsHTML = $('#total-generations');
// Shows the best phrase so far
var bestPhraseHTML = $('#best-phrase');
// Shows the best fitness so far
var bestFitnessHTML = $('#best-fitness');
// Shows the result of the reproduction process (child)
var processingHTML = $('#processing');
以下代码部分:
var condition = population.evaluate();
while (condition) {
// Processing
population.buildMatePool();
population.reproduce();
population.clearMatePool();
condition = population.evaluate();
}
我需要在每次迭代中更新DOM元素的值。我尝试使用 setInterval()和 setTimeout()进行不同的循环实现,但输出不同步。任何帮助都会有用。
P.S。我是JavaScript的新手。请原谅任何错误。
答案 0 :(得分:0)
while (condition) {}
所谓的阻塞代码,因为该循环在没有给浏览器实际渲染结果的情况下运行,你不会看到任何东西,可能是UI冻结。
您需要使用setTimeout
,setInterval
或建议动画requestAnimationFrame
但输出不同步
更改DOM以及页面上的可见内容是异步进程,而Js正在运行时,浏览器不会重新绘制。 while
循环正在运行JS。
有关详细信息,请查看here
答案 1 :(得分:0)
@philipp是对的。 setInterval(updateMarquee(), 10000);
是解决方案。
基本上requestAnimationFrame()
是:
requestAnimationFrame()
和setTimeout
不是)以下HTML / JS / CSS代码段演示了setInterval
。
requestAnimationFrame()
var currentPos = -200;
var element = document.getElementById("heading");
// Animation loop
function moveRight() {
currentPos += 5;
heading.style.left = currentPos + "px";
window.requestAnimationFrame(moveRight);
if(currentPos >= 800) {
currentPos = -200;
}
}
moveRight();
h1 {
position: relative;
border: 5px solid black;
text-align: center;
width: 200px;
}
div {
width: 800px;
height: 400px;
background-color: lime;
margin: 0 auto;
overflow: hidden;
}