Opened 11 years ago
Closed 11 years ago
#11470 closed feature (fixed)
Adding a builtin readyP promise
Reported by: | Owned by: | jaubourg | |
---|---|---|---|
Priority: | low | Milestone: | 1.8 |
Component: | core | Version: | |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Discussion with rick waldron [1] led to "Can you file a ticket: http://bugs.jquery.com so we can get a discussion going?" so here I am.
I've recently been teaching some JavaScript and some jQuery. I've also (less) recently discovered promises and just love how they work especially when it comes to synchronizing different async events with the $.when(promise1, promise2) construct.
An exercise I gave required to fetch an RSS feed, build a DOM fragment and append it to the DOM. In order to append something to the DOM, 2 things are required: 1) DOM is ready 2) RSS is retrieved This is a great opportunity to use $.when with 2 promises:
$.when($.get('rss.xml'), readyP).then(function(rss){
second argument purposefully ignored since I only care about synchronization
build a document fragment append to the document
});
Unfortunately, there is no readyP in jQuery, so I asked the students to add the following code before the $.when:
var readyDef = new $.Deferred(); var readyP = readyDef.promise(); $(function(){ readyDef.resolve() });
This really smells like boilerplate code to me. What about adding it to jQuery directly? Maybe defining a $.readyP? I have no strong opinion on what the resolution value could be. Maybe the document itself?
It has to be noted that some students did the following:
$(function(){
var rssP = $.get('rss.xml') rssP.then(function(rss){
build fragment append to DOM
})
});
It works, but the problem is that the xhr request isn't started before the document is ready (load event in old browser) which can be late. I think that having $.readyP included in the library would be a good incitation for both good programming style and performance at the same time.
Thanks
[1] https://twitter.com/#!/rwaldron/status/179627982019764224
Change History (8)
comment:1 Changed 11 years ago by
comment:2 Changed 11 years ago by
Or they could have done:
$.get('rss.xml').then(function(rss){ $(function(){ //build fragment append to DOM }); });
Perhaps the document could expose its ready-ness as a promise, perhaps via the .promise method of a predefined type. Then:
$.when($.get('rss.xml'), $(document).promise('ready')).then(function(rss){ //build fragment append to DOM });
comment:3 Changed 11 years ago by
We used to have a promise in jQuery.ready but when it was refactored into jQuery.Callbacks that was removed. A promise would be more useful as an external interface though, wouldn't be hard to put it back if we wanted to.
Anybody else have thoughts? In an ideal world I'd put in the promise and remove the $(document).bind("ready", fn)
fake event.
comment:4 Changed 11 years ago by
I don't feel comfortable exposing the promise directly but I see value in a $.ready promise.
Just adding a promise method on top of the $.ready function could make for some nice looking code:
// In core $.ready.promise = readyDeferred.promise; // In user code $.when( $.ready ).done(function() { // DOM IS READY });
comment:5 Changed 11 years ago by
Component: | unfiled → deferred |
---|---|
Priority: | undecided → low |
I've also needed this on multiple occasions and ended up doing the same thing as OP.
+1 for having a ready promise in core. @jaubourg's suggested syntax LGTM.
comment:6 Changed 11 years ago by
Milestone: | None → 1.8 |
---|---|
Status: | new → open |
Let's do it. I like the syntax too.
comment:8 Changed 11 years ago by
Component: | deferred → core |
---|---|
Resolution: | → fixed |
Status: | assigned → closed |
Good grief! I didn't expect wiki formatting. Sorry for the poor rendering. Reorganized codes snippets: https://gist.github.com/2030824