Bug Tracker

Opened 5 years ago

Closed 5 years ago

#11470 closed feature (fixed)

Adding a builtin readyP promise

Reported by: bruant.d@… Owned by: jaubourg
Priority: low Milestone: 1.8
Component: core Version:
Keywords: Cc:
Blocked by: Blocking:


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:


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.


[1] https://twitter.com/#!/rwaldron/status/179627982019764224

Change History (8)

comment:1 Changed 5 years ago by bruant.d@…

Good grief! I didn't expect wiki formatting. Sorry for the poor rendering. Reorganized codes snippets: https://gist.github.com/2030824

comment:2 Changed 5 years ago by fastfasterfastest

Or they could have done:

      //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 5 years ago by dmethvin

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 5 years ago by jaubourg

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() {

comment:5 Changed 5 years ago by sindresorhus

Component: unfileddeferred
Priority: undecidedlow

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 5 years ago by dmethvin

Milestone: None1.8
Status: newopen

Let's do it. I like the syntax too.

comment:7 Changed 5 years ago by jaubourg

Owner: set to jaubourg
Status: openassigned

ok, I'm on it.

comment:8 Changed 5 years ago by jaubourg

Component: deferredcore
Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.