There is no time to slice in javascript. Javascript is single-threaded (with the exception of web workers, which we are not talking about here). One javascript execution thread is executed before it is completed.
In your first code example, the animation does its work, and when it is complete, it calls your my_cpu_heavy_function .
In the second code example, the animation initializes and sets a timer for the first stage of the animation. Then it returns and moves on to the next line of code. The animation has just begun (and for a short time in the future, start the timer to do some more work) - it is not finished yet. Then my_cpu_heavy_function is my_cpu_heavy_function , and it starts all javascript execution until it is completed. Animation does not start at all while my_cpu_heavy_function is my_cpu_heavy_function . When it ends, a timer event will occur in which the animation set will be launched, and the animation will start working.
Animation may "look" like slicing time, but in reality it is not. jQuery animations move one step in the animation, and then set a timer for some small amount of time in the future, and they return back to the system. When this timer event fires, jQuery takes the next step in animation and so on. When the timer event fires, it puts the timer event in the javascript event queue. If javascript is not currently running, the timer callback starts immediately. If javascript is currently running, the timer event is simply in the event queue until the current javascript stream ends. When this thread ends, javascript looks in the event queue to see if there are any events waiting. If there is, then it calls the event callback.
Thus, in different parts of javascript there really is no time to chop. The two parts of the code that need to be run, not every given one, are some processor cycles, as happens with real threads in native code. In javascript, one piece of code runs before it completes, and then you can fire the next event. In things like javascript-based animations, time slicing can be modeled somewhat by doing tiny work and then setting a timer for some future time and returning to the system. Once you are done, some other parts of javascript may work, but it will also work until it is executed. If all parts of javascript do only a small amount of work, and then set a timer for their next work, then they can all work together and it will look like there is slicing time, but it only works because of the cooperation between them. If one function, for example my_cpu_heavy_function , comes and fights with the processor for a while, then no one starts. The animation will stop during the execution of my_cpu_heavy_function .
Some operations in the browser are performed using native code in the browser (for example, ajax calls, loading images, etc.). These asynchronous tasks can run in the background while javascript is running, but they wonβt notify javascript until the current javascript thread has finished and a new one has been launched with a notification callback.
As an example, suppose we have an image that takes 1 second to load and an intensive CPU function that takes 5 seconds. Then we get this code:
var img = new Image(); img.onload = function() { alert("image is loaded now"); } img.src = "xxx.jpg"; longFunctionThatTakesFiveSecondsToRun();
When we run this code, although it takes only 1 second to load inside the browser, the onload handler will not be called until longFunctionThatTakesFiveSecondsToRun() is executed 5 seconds later. It must wait until the current thread of execution has completed before the onload event can be processed.
If you want to know more about javascript event queues and asynchronous operations, see the corresponding answers:
How does JavaScript handle AJAX responses in the background?
JavaScript event handling race conditions
Can JS event handlers interrupt another handler?
Do I have to worry about race conditions with asynchronous Javascript?