为什么这个延期功能不起作用?

时间:2014-10-24 21:30:29

标签: jquery timer deferred

我创建了以下函数作为一种用于几个不同函数的通用计时器:

function timer (time, d) {
    var state=d.state();
    if (typeof t === "undefined") {
      state="pending";
    };
    if (state === "pending") {
      t = setTimeout(function() {
        timer(time, d);
      }, time);
    } else {
      t = undefined;
      return d.promise();
    }
  }

我知道它永远不会失败,因为我从不在任何地方拒绝d。这意味着在函数内部使用,因此除了t之外什么都不是全局的。这对我来说似乎相当直接,并且在我添加t的检查之前它正在工作。为什么我这样做是因为我希望计时器至少运行一次,无论如何。但是当我在开头添加t的检查时,解析处理程序不会触发。我使用以下代码进行测试:

var n=$.Deferred();
$.when(timer(2000,n))
 .done(function(p){
     console.log(p);
 });
 n.resolve('kittens');

我错过了什么吗? "小猫"永远不会记录。是否有setTimeout的东西我没有考虑,还是其他的东西?我甚至没有意识到这是jQuery的一个问题 - 但它看起来应该对我有用。

2 个答案:

答案 0 :(得分:1)

您未考虑的setTimeout()功能是从未来的事件转向中调用其函数参数。因此,timer函数不是真正的递归函数。

  

在其他地方一直在争论应该调用这种类似递归的行为 - 我称之为" extracursion" (其中有额外的原始拉丁语含义"外部")。*

无论如何,结果是: -

  • 如果您将未解决的Deferred传递给timer,则可以保证立即返回undefined。与此同时,计时器将快速地离开"在外面"直到Deferred得到解决,此时timer的最后一次调用会兴高采烈地将d.promise()返回到这个空气中。 任何内容都不会收到使用setTimeout调用的函数返回的值。

  • timer进行初始调用的唯一方法是返回undefined以外的任何内容,将其传递给已经解决的承诺,在这种情况下,您也可以使用#34;切断了中间人"写作:

$.Deferred().resolve('kittens').then(function(k) {
    console.log(k); //kittens
});

或更简单地说:

$.when('kittens').then(function(k) {
    console.log(k); //kittens
});

这是一种过于精细的实现方式:

console.log('kittens');

简而言之,整个timer练习,完全没有意义。

答案 1 :(得分:0)

很难确切地说出您正在尝试解决的问题。这是一个使用promises的通用计时器。它创造并回报并管理自己的承诺:

function timer(t, val) {
    var d = $.Deferred();
    setTimeout(function() {
        d.resolve(val);
    }, t);
    return d.promise();
}

timer(1000, "kitten").done(function(val) {
    console.log(val);
});

工作演示:http://jsfiddle.net/jfriend00/hsv213xn/

因此,您可以多次在多个地方使用它,因为它没有全局状态。

您不需要使用$.when(),因为它会返回一个拥有该.done()的承诺,因此您只需拨打.done()即可。

而且,这是它的链式版本:

function timer(t, val) {
    var d = $.Deferred();
    setTimeout(function() {
        d.resolve(val);
    }, t);
    return d.promise();
}

timer(1000, "kitten").then(function(val) {
    log(val);
    return timer(1000, "cat");
}).then(function(val) {
    log(val);
});

http://jsfiddle.net/jfriend00/0142emh0/