最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Use jquery done on "non-ajax" function - Stack Overflow

programmeradmin4浏览0评论

Can I use jquery done() on "non-ajax" functions. I get the error Uncaught TypeError: Cannot call method 'done' of undefined when I try to do something like this.

function countThreeSeconds() {
    var counter = 0,
    timer = setInterval(function () {

        if (counter == 3) {
            console.log("All done. That was three seconds.");
            window.clearInterval(timer);

        } else {
          console.log("Not there yet. Counter at: " + counter);
        }
        counter++;
    }, 1000);

}

(function(){
  var timer = countThreeSeconds().done(function(){
     alert("done");
  });

}());

Thanks

JSBIN

Can I use jquery done() on "non-ajax" functions. I get the error Uncaught TypeError: Cannot call method 'done' of undefined when I try to do something like this.

function countThreeSeconds() {
    var counter = 0,
    timer = setInterval(function () {

        if (counter == 3) {
            console.log("All done. That was three seconds.");
            window.clearInterval(timer);

        } else {
          console.log("Not there yet. Counter at: " + counter);
        }
        counter++;
    }, 1000);

}

(function(){
  var timer = countThreeSeconds().done(function(){
     alert("done");
  });

}());

Thanks

JSBIN

Share Improve this question asked Apr 18, 2013 at 21:28 12527481252748 15.4k34 gold badges116 silver badges241 bronze badges 1
  • 3 As you can see, you can't. jQuery has nothing to do with it. You can never call a method on undefined. jQuery methods don't just magically appear everywhere (thank goodness). You can call them on specific objects defined in the jQuery library and as described by jQuery's API. – user1106925 Commented Apr 18, 2013 at 21:30
Add a ment  | 

3 Answers 3

Reset to default 15

Make the non-ajax function return a promise object.

function countThreeSeconds() {
    var counter = 0,
    deferred = $.Deferred(),
    timer = setInterval(function () {

        if (counter == 3) {
            console.log("All done. That was three seconds.");
            window.clearInterval(timer);
            deferred.resolve();

        } else {              
            console.log("Not there yet. Counter at: " + counter);
            deferred.notify(counter);
        }
        counter++;
    }, 1000);
    return deferred.promise();

}

(function(){
  var timer = countThreeSeconds().done(function(){
     alert("done");
  }).progress(function(i){
     console.log("in progress...",i);
  });

}());

Since you're not returning anything from the function, it's perfectly valid JS behavior. To be able to use done on the function, return jQuery.Deferred object from it.

Something like this:

function countThreeSeconds() {
    var defer = $.Deferred(function() { // do your stuff here });
    return defer.promise();
}

Thomas, with something like this, you could make a Deferred object (and its promise) really work for you.

For example, you could make countThreeSeconds() a raw, more generalized function, and have all progress/done reporting performed in the calling function.

function countSeconds(n) {
    var dfrd = $.Deferred(),
        counter = 0,
        timer = setInterval(function() {
            counter++;
            if (counter < n) { dfrd.notify(counter); }
            else { dfrd.resolve(); }
        }, 1000);
    return {
        promise: dfrd.promise(),
        timer: timer
    };
}

(function() {
    var timerObj = countSeconds(3);
    timerObj.promise.progress(function(counter) {
        console.log("Not there yet. Counter at: " + counter);
    }).done(function() {
        clearInterval(timerObj.timer);
        console.log("All done. That was three seconds.");
        alert("done");
    });
}());

Thus, another function could call countSeconds() with a different value, and handle progress and done situations differently.

For example :

(function() {
    var timerObj = countSeconds(10);
    timerObj.promise.progress(function(counter) {
        $("#message").text("Counter = " + counter);
    }).done(function() {
        clearInterval(timerObj.timer);
        $("#message").text('Complete');
    });
}());
发布评论

评论列表(0)

  1. 暂无评论