Side navigation
#12044 closed feature (wontfix)
Opened July 09, 2012 02:10PM UTC
Closed January 04, 2013 10:15PM UTC
ready callback should always be called asynchronously
Reported by: | tj@crowdersoftware.com | Owned by: | |
---|---|---|---|
Priority: | low | Milestone: | 1.9 |
Component: | deferred | Version: | 1.7.2 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
The documentation of ready
says:
If .ready()
is called after the DOM has been initialized, the new handler passed in will be executed immediately.
...and by "immediately" it means "synchronously."
Which is a problem: The handler should always be called asynchronously, even if the DOM is ready. This prevents ready
from having chaotic behavior. For instance, it's impossible to look at this code and determine the order in which "B" and "C" are logged:
console.log("A"); jQuery(function($) { console.log(B"); }); console.log("C");
In the normal case (DOM not yet ready when ready
is called), we'll get
A C B
...but if the DOM is already ready, we'll get
A B C
This allows bugs to slip in, where there is an undetected dependency on the order of B and C and a script is only tested in one situation or the other.
Somewhat gratuitous example showing the three situations in which ready
might be called (1. DOM not ready; 2. During another ready
handler; 3. DOM ready), and how they behave: http://jsbin.com/ezowij The output is:
Outer: ACB Inner
: ACB Delayed
: ABC
Note the third is different. My belief is that if a callback ''may'' be asynchronous, it should always be asynchronous, and so I'd rather see consistency.
Attachments (0)
Change History (11)
Changed July 09, 2012 02:12PM UTC by comment:1
Changed July 10, 2012 12:39AM UTC by comment:2
component: | unfiled → deferred |
---|---|
milestone: | None → 1.9 |
priority: | undecided → low |
status: | new → open |
Changed September 09, 2012 01:10AM UTC by comment:3
type: | enhancement → feature |
---|
Bulk change from enhancement to feature.
Changed December 03, 2012 06:07PM UTC by comment:4
blockedby: | → 10467 |
---|
Changed December 09, 2012 05:30PM UTC by comment:5
Leaving this open since it can be solved with setTimeout. Is it worth adding that though?
Changed December 09, 2012 06:28PM UTC by comment:6
Replying to [comment:5 dmethvin]:
Is it worth adding that though?
I'd say so, for the consistent behavior.
Changed December 09, 2012 06:39PM UTC by comment:7
The downside is that it probably adds at least 16ms of delay to document ready for everyone, since APIs like setImmediate()
aren't available.
Changed December 10, 2012 07:59AM UTC by comment:8
Replying to [comment:7 dmethvin]:
The downside is that it probably adds at least 16ms of delay to document ready for everyone, since APIs like setImmediate()
aren't available.
If you're optimizing to that level, you don't use ready
anyway, although in my tests setTimeout
only routinely adds 15ms in IE; on Chrome I get 7ms on average, Opera about 7.5ms, and Firefox less than 4ms.
I would also advocate only using setTimeout
when the DOM is already ready, but a quick look at the latest suggests ready
has been promise
-ified which might make that difficult.
Changed December 11, 2012 08:32PM UTC by comment:9
I've started looking at this today and will take ownership of it if no one else has made any progress.
Changed December 12, 2012 01:41AM UTC by comment:10
It's a -1 for me. The consistency argument seems rather specious to me.
Changed January 04, 2013 10:15PM UTC by comment:11
resolution: | → wontfix |
---|---|
status: | open → closed |
This really comes down to the same problem we've argued ad nauseum with promises and their sync/async resolution. For better or worse, we have quite a bit of code that depends on the current behavior and we've documented that the callback is called "immediately" when the DOM is ready.
The good news is that someone who needs the async resolution is free to guarantee that with a setTimeout()
inside their own code. If were were to "fix" this, it wouldn't be possible to get the synchronous behavior back.
If/when #10467 is resolved, this will automatically happen :-)