【问题标题】:Use jquery done on "non-ajax" function在“非ajax”功能上使用jquery
【发布时间】:2013-04-18 21:28:10
【问题描述】:

我可以在“非 ajax”函数上使用 jquery done() 吗?当我尝试做这样的事情时,我收到错误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

【问题讨论】:

  • 如您所见,您不能。 jQuery 与它无关。你永远不能在undefined 上调用方法。 jQuery 方法不仅仅神奇地出现在(谢天谢地) 中。您可以在 jQuery 库中定义的特定对象上调用它们,并按照 jQuery 的 API 的描述。

标签: javascript jquery jquery-deferred


【解决方案1】:

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

}());

【讨论】:

  • 这真是太好了。并且非常有意义。现在很明显,我不能指望一个正常的函数自动访问所有那些延迟的方法,比如 jquery ajax。非常感谢!
  • console.log() 接受无限(我认为?)数量的参数,它只允许您记录不止一件事,或标记每个日志以便您知道它是什么。
【解决方案2】:

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

类似这样的:

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

【讨论】:

  • 你为什么要传递一个函数给$.Deferred?这不是您的代码所在的位置。
  • @RocketHazmat 在函数中这样做没有错。 pastebin.com/CWXWcmkS
  • @KevinB:我刚刚看了文档。猜你是对的,但我从未见过这样做。
  • @KevinB:哇!我喜欢这种语法。 :-)
  • @RocketHazmat 我也是。使用我在回答中使用的语法通常更容易将其添加到现有代码中。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    相关资源
    最近更新 更多