9

我可以done()在“非 ajax”函数上使用 jquery。Uncaught TypeError: Cannot call method 'done' of undefined当我尝试做这样的事情时,我得到了错误。

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");
  });

}());

谢谢

JSBIN

4

3 回答 3

15

使非 ajax 函数返回一个 promise 对象。

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);
  });

}());
于 2013-04-18T21:32:54.397 回答
2

由于您没有从函数返回任何内容,因此这是完全有效的 JS 行为。为了能够done在函数上使用,从它返回jQuery.Deferred对象。

像这样的东西:

function countThreeSeconds() {
    var defer = $.Deferred(function() { // do your stuff here });
    return defer.promise();
}
于 2013-04-18T21:30:21.793 回答
1

Thomas,通过这样的方式,您可以让 Deferred 对象(及其承诺)真正为您工作。

例如,您可以创建countThreeSeconds()一个原始的、更通用的函数,并在调用函数中执行所有进度/完成报告。

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");
    });
}());

因此,另一个函数可以调用countSeconds()不同的值,并以不同的方式处理进度和完成情况。

例如 :

(function() {
    var timerObj = countSeconds(10);
    timerObj.promise.progress(function(counter) {
        $("#message").text("Counter = " + counter);
    }).done(function() {
        clearInterval(timerObj.timer);
        $("#message").text('Complete');
    });
}());
于 2013-04-18T22:04:52.680 回答