'Delay method takes too long on javascript
I'm new to HTML & Javascript and I'm learning the basics of drawing in a canvas. I tried to create a visualization of some search algorithms like BFS and DFS.
So I came up with the following code(shows 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();
}
}
}
Update function looks like this:
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);
}
Whenever I try to call update() without the delay, the program waits until the entire search is completed and then updates. I tried finding solutions for this, and I tried using setTimeout() and setInterval() but they didn't work, so I just added a delay.
Delay looks like this:
async function delay() {
// delay_ms is a global
return new Promise(resolve => setTimeout(resolve, delay_ms));
}
But the problem with this method is that even with a very small delay (0 or 1ms) the program is extremely slow. I was wondering if there was a way to somehow reduce the delay.
Solution 1:[1]
I solved this by only calling the delay and update function once every n iterations. Example:
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]);
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ashwin Alagiri-rajan |
