I have this function:
const BFS = (graph, start) => {
let queue = []
queue.push(start)
let visited = []
visited[start] = true
while (queue.lenght > 0) {
let node = queue.shift()
for (var i=1; i<graph[node].length; i++) {
if (graph[node][i] && !visited[i]) {
visited[i] = true
queue.push(i)
}
}
}
}
What I want is to have a button that when I press it, It stops the execution of the function, and if I press it again, it resumes the execution from the same place it stopped on.
Is that possible ? and if so, how to do it ?
Advertisement
Answer
Other solution with generator functions, read about this feature on MDN
Note, that here we can proceed further one step at a time!
General idea:
- Put
yieldstatements in your method, in places where you want to pause it. - Create instance of your generator and write code that will call its
.next()method and will handle repeated calls. - Note, that you can get values from generator and also pass in with
.next()method.
// generator function that we want to stop/continue in the middle
function* stoppableMethod() {
// here is the implementation of the algorithm
// that we want to control
let i = 0;
while (true) {
// note that yield is inside infinite loop!
yield i;
i += 1;
}
}
const generatorInstance = stoppableMethod();
// tick generator and perform update of the indicator
const nextStep = () => {
const { value } = generatorInstance.next();
document.getElementById("indicator").innerHTML = value;
}
// state to keep track of the setInterval id
const state = {
timeoutId: 0,
}
// start method progression
const start = () => {
// do not start interval if there is already an interval
// running
if (state.timeoutId === 0) {
state.timeoutId = setInterval(() => nextStep(), 1000)
}
}
// clear timeout to stop auto porgress
const stop = () => {
clearTimeout(state.timeoutId);
state.timeoutId = 0;
}
// tick further one step
const stepForward = () => nextStep()<button onclick="start()">start</button> <button onclick="stop()">pause</button> <button onclick="nextStep()">one step forward</button> <div id="indicator">0</div>