繁体   English   中英

等待递归jQuery函数完全完成

[英]Wait for a recursive jQuery function to completely finish

另一个应该很简单,但却给我带来麻烦。 我正在尝试学习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."));

}

当运行此命令时,“ Finished”警报(我要推迟)将在第一次执行递归脚本后运行,因此当仅打印一个字母(而不是预期的结果)时,它将显示。 但是,一旦所有字母都已打印并且递归完成,“完成”警报将正确显示,因此似乎我的defer变量直到那时才应解决。 谁能帮助我发现为什么在此提早调用“完成”警报? 任何帮助表示赞赏!

编辑:我意识到我不小心发布了我的代码的一个稍旧的版本。 已使用正确的版本进行了更新(运行时的行为相同)。

startButtonClick功能,您不需要调用.promise()上的结果showText ,因为你已经在做的里面showText 接下来, then回调的参数应该是一个函数,现在您立即调用alert函数,而不是将其作为函数传递,这就是为什么它立即显示的原因,因此请将其包装在一个函数中:

function(){ alert("Finished."); }

这是一个带有代码的jsfiddle: http : //jsfiddle.net/RnLXF/

发生这种情况是因为您实际上是在立即执行alert功能,而不是传递功能引用。

改为这样做:

.then(alert.bind(null, 'finished'));

要么

.then(function () {
    alert('finished');
});

这是一个小提琴,其中很多东西都包裹在一个漂亮的小物体中: http : //jsfiddle.net/YVZKw/3/

正如plalxctcherry所说,最大的问题是您的.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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM