Jabda
Jabda

Reputation: 1792

JQuery Deferred how to use resolve and promise to determine function end

I have a in an html page that I'd like to show a spinner on while a JQuery function is running. Since its asynchronous I am trying to use deferred to determine when the function completed

the code in the html page

 var req = jslongfunc(value);
 req.done(function( response){
           spinner.stop();
 });

The code in the JS page that contains jslongfunc

function jslongfunc() {
   rdef = $.Deferred();
   $.getJSON('mycode, function(data){
   ... do lots of stuff here ...
  });
  setTimeout(function () {
             r.resolve();
        }, 4500);
   return r.promise();

The spinner seems to run for 4500 regardless of when the jslongfunc finished all its code. I know when it finishes because it draws something. I thought r would return and .done would execute if the function finished before the time out. What am I doing wrong?

Upvotes: 0

Views: 503

Answers (2)

wes
wes

Reputation: 168

Your promise is resolving only when your setTimeout function is calling r.resolve() after 4500ms. You need to call r.resolve() when all your stuff is done. Maybe something like this...

// function definition
var jslongfunc = function(defr) {
    //... do lots of stuff here ...
    defr.resolve();
}

// promise helper
var promise = function (fn) {
    var dfd = $.Deferred(fn);
    return dfd.promise();
}
// init the deferred by using the promise helper above and then attach 'done' callback to stop spinner
var rdef = promise(jslongfunc).done(function (response) {
    spinner.stop();
}).fail(function (response) {
    // handle promise failure.
});

Update

Well now that you put up your using $.getJSON you can do the following.

function jslongfunc(value) {
  var jqxhr = $.getJSON(url, function (data) {
    // THIS IS YOUR FIRST promise callback
    // do some stuff with the json you just got
  });
  // return the promise
  return jqxhr;
}

// now handle the spinner stoppage
jslongfunc(value).done(function () {
  spinner.stop();
}).fail(function (data) {
  // handle function failure here
});

Upvotes: 1

TimSPQR
TimSPQR

Reputation: 2984

Here is a little FIDDLE that I use to hit the Google financial API for stock quotes.

I've added the Ajax events beforesend, complete that turns some gears off and on (very short period of time for this call).

But it will probably give you a start.

Edit: Here's a second FIDDLE with more compact code.

JS

$('.putmehere1').hide();
var quotevalue;
var symboltopass = "NYSE:SDY";

$.ajax({
         type: "GET",
          url: "https://finance.google.com/finance/info",
        async: false,
     dataType: 'JSONP',
         data: {
                client: 'ig',
                     q: symboltopass
                }
 })
.done( function(data){
                                 var stockInfo = data[0];
                                 console.log( data[0] );
                                 quotevalue = stockInfo.l;
                                 $('.putmehere2').html( '#2 - ' + quotevalue);
                          });
$.ajax({
   beforeSend: function(){
      $('.putmehere1').show();
   },
   complete: function(){
      $('.putmehere1').hide();
   }
 });

Upvotes: 0

Related Questions