我创建了以下函数作为一种用于几个不同函数的通用计时器:
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的一个问题 - 但它看起来应该对我有用。
答案 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);
});