سؤال

or ecmascript but i wonder if how it actually happens depends more on the exact implimentation.

javascript is technically single threaded.

but if i do something like

$myDIv.animate({
    height:"100px"
});

does it make any difference if i do

A.

$myDIv.animate({
    height:"100px"
}, null, my_cpu_heavy_function);

or B.

$myDIv.animate({
    height:"100px"
});
my_cpu_heavy_function();

because in the second one the animation would be fighting for processing time with the cpu heavy function and so the look of the animation would suffer, right?

So does Javascript stop executing at the end of a synchronous block of code or does it cut off one block at any random point to allow another block running asynchronously to be processed?

هل كانت مفيدة؟

المحلول

does it make any difference if i do A or B

Yes it will make a difference.

The second version doesn't so much fight for processing time. It's more like the my_cpu_heavy_function will occupy all processing time once it begins, assuming it is synchronous.

In other words, once a bit of synchronous code begins, it does not end until complete, irrespective of any timed asynchronous code that may be scheduled to run. The async code will always be forced to wait for the synchronous code to complete.

So what will happen will be that the animation will begin, and perform its initialization, but then the my_cpu_heavy_function will immediately start, and block the rest of the animation until it is complete.

نصائح أخرى

There is no time slicing in javascript. Javascript is single threaded (except for web workers which we aren't discussing here). One thread of javascript execution runs until it completes.

In your first code example, the animation does its thing and when it's completely done, it calls your my_cpu_heavy_function.

In your second code example, the animation initializes itself and sets a timer for it's first animation step. Then it returns and goes onto the next line of code. The animation has only started (and set a timer for a short time in the future to do some more work) - it has not completed. Then, your my_cpu_heavy_function runs and it hogs the entire javascript execution until it's done. The animation does not run at all while my_cpu_heavy_function is running. When it finishes, the timer event that the animation set will fire and the animation will go about running.

Animations may "look" like time slicing, but they aren't really. 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 that timer event fires, jQuery does the next step in the animation and so on. When a timer event fires, it puts a timer event into the javascript event queue. If no javascript is currently running, the timer callback is started immediately. If javascript is currently running, then the timer event just sits in the event queue until the current javascript thread finishes. When that thread finishes, javascript looks in the event queue to see if there are any events waiting. If there are, then it calls the event callback.

As such, there really is no time slicing for different pieces of javascript. Two pieces of code wanting to run are not each given some CPU cycles like would happen with real threads in native code. In javascript one piece of code runs until it's done and then the next event can be started. In things like javascript-based animations, time slicing can be somewhat simulated by doing a tiny amount of work and then setting a timer for some future time and returning to the system. As soon as you finish executing, some other piece of javascript can run, but it also will run until it's done. If all pieces of javascript only do tiny amounts of work and then set a timer for their next piece of work, then they can all cooperate and it will appear like there is time slicing, but it only works because of the cooperation among them all. If one function like my_cpu_heavy_function comes along and hogs the CPU for awhile, nobody else runs during that time. The animation would stop while my_cpu_heavy_function was running.

Some operations in a browser are carried out by native code in the browser (such as ajax calls, loading of images, etc...). These asynchronous tasks can proceed in the background while javascript is running, but they won't notify javascript until the current thread of javascript execution finishes and a new one with the notification callback can be started.

As an example, let's assume we have an image that takes 1 second to load and a CPU intensive function that takes 5 seconds to run. We then have this code:

var img = new Image();
img.onload = function() {
    alert("image is loaded now");
}
img.src = "xxx.jpg";
longFunctionThatTakesFiveSecondsToRun();

When we run this code, even though the image only takes 1 second to load internally in the browser, the onload handler won't get called until longFunctionThatTakesFiveSecondsToRun() is done running 5 second later. It has to wait until the current thread of execution is done before the onload event can be processed.

If you want to know more about javascript event queues and asynchronous operations, see these related answers:

How does JavaScript handle AJAX responses in the background?

Race conditions with JavaScript event handling?

Can JS event handlers interrupt execution of another handler?

Do I need to be concerned with race conditions with asynchronous Javascript?

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top