另一个应该简单,但却给我带来麻烦。我试图了解jQuery的.Deferred()和.promise()功能,以延迟某些操作,直到递归函数完全完成。目前,我的代码类似于以下内容:
function showText(setTarget, setMessage, setIndex, setInterval) {
var defer = jQuery.Deferred();
var doShowText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { doShowText(target, message, index, interval); }, interval);
}
else {
alert("Done!");
defer.resolve();
}
};
doShowText(setTarget, setMessage, setIndex, setInterval);
return defer.promise();
}
function startButtonClick() {
displayElement($("#getElement"));
showText($("#getElement > h1"), "This text will slowly write to the screen.", 0, 50).promise()
.then(alert("Finished."));
}
当它运行时,“完成”警报(我试图推迟)在第一次执行递归脚本后运行,因此当只打印一个字母时(而不是预期的结果)它将出现。但是,一旦打印完所有字母并且递归完成后,“完成”警报就会正确显示,因此似乎我的延迟变量在此之前不应被解析。任何人都可以帮助我发现为什么在这里早期调用“完成”警报?任何帮助表示赞赏!
编辑:我意识到我不小心发布了稍微旧版本的代码。它已使用正确的版本进行更新(运行时的行为相同)。答案 0 :(得分:2)
在startButtonClick
函数中,您无需在.promise()
的结果上调用showText
,因为您已经在showText
内执行此操作。接下来,then
回调的参数应该是一个函数,现在你立即调用alert函数,而不是将它作为函数传递,这就是它立即显示的原因,所以只需将它包装在一个函数中:
function(){ alert("Finished."); }
这是一个包含代码的jsfiddle:http://jsfiddle.net/RnLXF/
答案 1 :(得分:2)
这种情况正在发生,因为您实际上是在执行alert
函数而不是传递函数引用。
请改为:
.then(alert.bind(null, 'finished'));
或者
.then(function () {
alert('finished');
});
答案 2 :(得分:1)
这里有一个小提琴,包裹着一个漂亮的小物件: http://jsfiddle.net/YVZKw/3/
正如 plalx 和 ctcherry 已经说过,最大的问题是你的.then电话中缺少一个功能。
<强> HTML 强>
<a href='javascript:void(0)'>Start</a>
<div id='sampleElement'>
<h1></h1>
</div>
<强>的JavaScript 强>
$('a').on('click', function(){
new ShowText(
$("#sampleElement > h1"),
"I will slowly write text to the screen.",
50
)
.done(function(){
alert("Finished.")
});
});
function ShowText(target, message, speed)
{
me = this;
me.target = target;
me.message = message;
me.index = 0;
me.speed = speed;
me.defer = new $.Deferred();
me.interval = setInterval(function() {
me.target.append(me.message[me.index++]);
if (me.index > me.message.length) {
clearInterval(me.interval);
me.defer.resolve();
}
}, me.speed);
return me.defer;
}