0

I have created a JavaScript version of the Little Man Computer based on the Java one at http://www.atkinson.yorku.ca/~sychen/research/LMC/LMCHome.html

I have it working in by stepping through each instruction. I have a function called stepCode() that does this.

What I want is a function that will run the program, pausing for a second between each step until the simulated program ends.

The code I have is this:

function runProgram()
{
 var milliseconds = 1000;
 var timeOut;
 programRunning = true;
 while(programRunning)
 {
 timeOut = setTimeOut(stepCode(), milliseconds); 
 }
}

This seems does not work. It still performs all the stepCode() calls one after the other very quickly. I want to pause between each stepCode() call.

I'm obviously doing something wrong. Any ideas?

asked Feb 24, 2014 at 15:41
1
  • When you have code like foo(bar()) then bar is called first and its return value is passed to foo. Arguments are always evaluated first. Commented Feb 24, 2014 at 15:52

4 Answers 4

1

You should use setInterval instead of setTimeout. Additionally, you need to reference the function, not call the function:

var timeOut; // global timeout variable to ensure both methods have access to it.
function runProgram() {
 var milliseconds = 1000;
 timeOut = setInterval(stepCode, milliseconds); // use setInterval instead of setTimeout
}
function stepCode {
 // ... code processing here ...
 // I assume you are setting programRunning to false at some point in this method.
 // Instead of setting programRunning = false, you would do:
 clearInterval(timeOut);
 // Note, if you only have one timeout interval set, you can use clearInterval();
}

setInterval will cause the stepCode function to run every 'milliseconds' until you call clearInterval(timeOut);; setTimeout will only queue it up once. Anything that is queued via setTimeout will not execute until the current flow of code has been completed. As a result, programRunning will run and queue up several setTimeout executions. Once the programRunning variable hit false, the current code flow will finish and ALL of the queues will wait 1 second, and effectively execute all at the same time, or in rapid succession.

When you pass in a method call (e.g. stepCode()), it will call the method. You have to pass a reference to the function stepCode (notice no parens), to ensure that it knows what to run each time it executes.

This Fiddle Demo simulates a counter, which is common thing people attempt to execute using setInterval. It demonstrates the basic concept and use of setInterval.

answered Feb 24, 2014 at 15:44
Sign up to request clarification or add additional context in comments.

5 Comments

I assume that also means getting rid of the while loop?
@FelixKling Yes. I'll post a full solution, since the while loop would no longer be valid.
Tried both setInterval and setTimeout. You are right about it repeatedly calling the function. Using either method locks up the browser with repeated function calls.
It could be because you are losing scope of your timeOut variable; it isn't accessible in the stepCode method. I've modified my solution to make timeOut global, as well as posted a demo.
I got rid of the while loop and put the clearInterval(timeOut) inside an if statement checking to see if the programRunning flag was set to false. Thanks a lot. You have helped me fix the last little problem I had with my code.
1

In addition to suggested setInterval use that will call stepCode at 1 second intervals until cleared (or until the page is reloaded), and correction of removing () after stepCode that results in immediate stepCode executon, you can still use setTimeout if they are chained as shown below. Depending on what stepCode does and how long it takes, this solution has an advantage of ensuring that there is 1 second of idle time between the end of the previous and the beginning of the next stepCodes.

var milliseconds = 1000;
function runProgram()
{
 programRunning = true;
 stepCodeWrapper();
}
function stepCodeWrapper() {
 if (programRunning) {
 stepCode();
 setTimeOut(stepCodeWrapper, milliseconds); 
 } 
}
answered Feb 24, 2014 at 15:45

Comments

0

Just try with:

timeOut = setInterval(stepCode, milliseconds);
answered Feb 24, 2014 at 15:45

Comments

0

Bic, thanks for your swift response. You are correct about the programRunning flag being set to false inside the stepCode() function. I've set it as a global variable so that I could possibly halt the program by pressing a button, but thats another problem.

Tried both setInterval and setTimeout. You are right about it repeatedly calling the function. Using either method locks up the browser with repeated function calls. This is probably as its in a while loop. I cannot think of another was to repeatedly call the stepCode() function otherwise.

I sort of understand the difference between setInterval & setTimeout. Thanks, and I understand that would make the while loop redundant, but then how to stop it calling the stepCode function when the programRunning flag is set to false?

answered Feb 24, 2014 at 16:23

1 Comment

I modified my answer to put timeOut as a global. You would just need to replace your programRunning = false with clearInterval(timeOut);

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.