13

I'm surprised I can't find a clear answer to this. So, in jQuery, you can do this:

$(someElements).fadeOut(1000);
$(someElements).remove();

Which, will start a fadeOut animation, but before it finishes executing in the 1 second duration, the elements are removed from the DOM. But how is this possible? I keep reading the JavaScript is single threaded (see also: Is JavaScript guaranteed to be single-threaded?). I know I can do either:

$(someElements).fadeOut(1000).promise().done(function() { 
    $(someElements).remove();
});

or even better:

$(someElements).fadeOut(1000, function() { 
    $(this).remove(); 
});

What I don't understand is how JavaScript runs in a "single thread" but I'm able to use these jQuery functions that execute asynchronously and visibly see the DOM change in different places at the same time. How does it work? This question is not: "How do I fix this".

Community
  • 1
  • 1
Sam Rueby
  • 5,914
  • 6
  • 36
  • 52

5 Answers5

6

jQuery animations (and pretty much all javascript-based animations) use timers to run their animations. The call to .fadeOut() just STARTS the animation and it doesn't complete until some time later when a series of timer operations are done.

This is all still single-threaded. .fadeOut() does the first step of the animation, it sets a timer for the next step and then the rest of your javascript (including the .remove()) runs until completion. When that javascript thread finishes and the time elapses for the timer, the timer fires and the next step of the animation happens. Finally when all steps of the animation have completed, jQuery calls the completion function for the animation. That is a callback that allows you to do something when the animation is done.

That is how you fix this issue:

$(someElements).fadeOut(1000, function() {
    $(this).remove();
});

You use the animation completion function and only remove the item when the animation is done.

ataddeini
  • 4,931
  • 26
  • 34
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • If you want asynchronous execution you might consider a web worker or use the (currently) experimental River Trail OpenCL bridge if you're doing intense data processing. – FlavorScape Mar 22 '12 at 23:26
  • I actually prefer JSTween because it can handle any properties. – FlavorScape Mar 22 '12 at 23:28
  • 1
    @FlavorScape - Web workers can't interact with the DOM so they aren't much help for animations. – jfriend00 Mar 22 '12 at 23:43
  • Well you can use it to compute multi-body complex animation where each frame is a little more intense than just tweening. Then you can gather your final data and update the coordinate in the update cycle when the result comes back. I prefer River Trail/OpenCL though, it should be getting standardized soon for webkit/ff/chrome – FlavorScape Apr 05 '12 at 23:06
1

There is a setInterval handler in jQuery that performs transformations on all registered animation properties. If you're coming from as3, think of it as an EnterFrame handler, or like a Draw method in OpenGL

FlavorScape
  • 13,301
  • 12
  • 75
  • 117
  • I think in recent versions of jQuery, it may use requestAnimationFrame handler (event dispatched by the browser) as the update/draw function – FlavorScape Mar 22 '12 at 23:18
  • requestAnimationFrame has been in and out of jQuery. It was in for awhile, then was pulled out because of some problems. I don't currently see it in the version of 1.7 that I have source open for. – jfriend00 Mar 22 '12 at 23:21
  • @jfriend00 you are correct http://stackoverflow.com/questions/7999680/why-doesnt-jquery-use-requestanimationframe – FlavorScape Mar 22 '12 at 23:27
  • Yeah, I have an answer in that very question. – jfriend00 Mar 22 '12 at 23:46
0

You ca use delay() to wait for a certain time or use a callback for the animation, changing the fadeOut with animate. jQuery uses setTimeout to animate and queues.

Ricardo Souza
  • 16,030
  • 6
  • 37
  • 69
0

In much the same way that operating systems 20 years ago did multi-tasking. There were no threads, there were just a list of things that needed attention and a controller that would give attention to things based on the list.

A single thread just iterates through the list over and over services all the things that need servicing. The only difference here is that some things have a wait period associated. They are in the list, but are flagged to service only after a certain period. It's a very basic scheduler implementation essentially. The kernel on a computer does the same thing. Your CPU can only execute a few programs concurrently, and even then, only somewhat. The operating system kernel has to decide who gets attention on a millisecond by millisecond basis (see jiffies). Javascript's "kernel" or runtime does the same thing, but essentially like it's running on a CPU with only one core.

This doesn't talk about things like interrupt queues and such which a CPU can cope with, and I'm not sure Javascript has any analogue, but at a simple level, I think it's a fair representation.

PlexQ
  • 3,154
  • 2
  • 21
  • 26
0

Single Threading has nothing to do with Asynchronous programming. http://social.msdn.microsoft.com/Forums/uk/csharplanguage/thread/3de8670c-49ca-400f-a1dc-ce3a3619357d

If you have only one thread on which you can execute instructions, it won't /always/ be executing. During those empty spots, that's opportunity for more work. Asynchronous programming just breaks up the work into re-entry capable blocks and the thread jumps around to where it's needed. (Conceptual explanation)

In this case, your question might more appropriately be: Why isn't this a blocking call? In which case the answer is pretty clear that it's to separate the UI animations from data calls. The whole JS environment shouldn't block for 1 second while taking small slices to animate an element which it could be retrieving or transforming data, queuing up animation for other elements, etc.

Erik Noren
  • 4,279
  • 1
  • 23
  • 29