Soy nuevo en HTML y Javascript y estoy aprendiendo los conceptos básicos de dibujo en un lienzo. Traté de crear una visualización de algunos algoritmos de búsqueda como BFS y DFS.
Así que se me ocurrió el siguiente código (muestra BFS):
async function bfs_iterative({x,y}) { let q = [] q.push({x,y}); while(q.length > 0) { let v = q.shift(); let neighbors = get_neighbors(v); for(let i = 0; i < neighbors.length; ++i) { let neighbor = neighbors[i]; if(neighbor.x == end_coords.x && neighbor.y == end_coords.y) { return; } main_array[neighbor.y][neighbor.x] = grid_kind['visited']; q.push(neighbors[i]); await delay(); update(); } } }La función de actualización se ve así:
function update() { clear(); for(let i = 0; i < grid_height; ++i) { for(let j = 0; j < grid_width; ++j) { switch(main_array[i][j]) { case grid_kind['path']: draw_rect(j * unit_width, i * unit_height, unit_width, unit_height, background_color); break; case grid_kind['wall']: draw_rect(j * unit_width, i * unit_height, unit_width, unit_height, foreground_color); break; case grid_kind['visited']: draw_rect(j * unit_width, i * unit_height, unit_width, unit_height, visited_color); break; case grid_kind['solution']: draw_rect(j * unit_width, i * unit_height, unit_width, unit_height, solution_color); break; } } } draw_rect(start_coords.x * unit_width, start_coords.y * unit_height, unit_width, unit_height, start_color); draw_rect(end_coords.x * unit_width, end_coords.y * unit_height, unit_width, unit_height, end_color); } Cada vez que trato de llamar a update() sin demora, el programa espera hasta que se completa la búsqueda completa y luego se actualiza. Intenté encontrar soluciones para esto, e intenté usar setTimeout() y setInterval() pero no funcionaron, así que solo agregué un retraso.
El retraso se ve así:
async function delay() { // delay_ms is a global return new Promise(resolve => setTimeout(resolve, delay_ms)); }Pero el problema con este método es que incluso con un retraso muy pequeño (0 o 1ms) el programa es extremadamente lento. Me preguntaba si había una manera de reducir de alguna manera la demora.
Resolví esto llamando solo a la función de delay y update una vez cada n iteraciones. Ejemplo:
async function bfs_iterative({x,y}) { let q = [] q.push({x,y}); let ctr = 0; let n = 5; while(q.length > 0) { // runs every 5 iterations ctr = (ctr + 1) % n; if(ctr == 0) { await delay(); update(); } let v = q.shift(); let neighbors = get_neighbors(v); for(let i = 0; i < neighbors.length; ++i) { let neighbor = neighbors[i]; if(neighbor.x == end_coords.x && neighbor.y == end_coords.y) { return; } main_array[neighbor.y][neighbor.x] = grid_kind['visited']; q.push(neighbors[i]); } } }