小提琴:https://jsfiddle.net/x89ja8r8/
我一直在四处寻找链接函数异步的快速方法。 Stackoverflow提供了许多“相同”的解决方案,但是当我尝试它时,总会出现问题。
在下面的例子中,我有3个功能。我尝试使用$ .Deffer()异步链接它们。
期望:div将在5500ms的持续时间内动画更改其尺寸,然后 div将在2000ms的持续时间内淡入0.25不透明度,然后 div innerHTML将更改为DONE!
结果:div更改其innerHTML(来自fn3())同时,并更改其维度(来自fn1()),持续时间为5500毫秒,然后它在2000ms的持续时间内衰减到0.25不透明度(来自fn2())。
function fn1() {
$("#result").animate({
width: 800,
height: 800
}, 5500);
}
function fn2() {
$("#result").animate({
opacity: 0.25
}, 2000);
}
function fn3() {
$("#result").html("DONE!");
}
var dfr = $.Deferred();
dfr.done(fn1, fn2, fn3).resolve();
这里有什么问题?如果它根本不起作用,则fn1()和fn2()之间不应该存在异步。结果清楚地表明fn2()确实等待fn1()完成,但是fn3()只是在没有等待的情况下开始。
答案 0 :(得分:0)
dfr.done(fn1,fn2,fn3)将同时执行所有功能,而不是按顺序执行。由于$ .animate()是一个异步操作,根据jQuery的文档,它可以接受一个动画完成后将被调用的回调,或者你可以让它返回一个promise。然后,您必须使用$ .Deferred.then()链接承诺,如下所示:
$(document).ready(function() {
function fn1() {
return $("#result").animate({
width: 800,
height: 800
}, 5500).promise();
}
function fn2() {
return $("#result").animate({
opacity: 0.25
}, 2000).promise();
}
function fn3() {
return $("#result").html("DONE!").delay(2000).promise();
}
function fn4() {
var fn4Dfr = $.Deferred();
setTimeout(function() {
$("#result").html("Okay!");
fn4Dfr.resolve();
}, 2000);
return fn4Dfr;
}
var dfr = $.Deferred();
dfr.then(fn1).then(fn2).then(fn3).then(fn4);
dfr.resolve();
});
fn3使用延迟,其行为类似于setTimeout,fn4使用setTimeout,因此我们创建了一个可以根据需要解析的promise(并立即返回promise)。
答案 1 :(得分:0)
对于这个特定用例,您可以使用简单的回调而不是$.Deferred
:
$("#result")
.animate({ width: 800, height: 800 }, 5500)
.animate({ opacity: 0.25 }, 2000, function () {
$(this).text('Done!')
})

div {
width: 100px;
height: 100px;
background-color: #ccc;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result">Result</div>
&#13;
答案 2 :(得分:0)
我一直在寻找一种快速链接函数异步的方法。
done
method不会链接任何东西。它安装要运行的处理程序,如果你传递多个参数,它将同时调用这些函数。永远不要使用done
。
你要找的是承诺的then
method,它会返回一个新承诺,它将通过回调的结果解决(等待它返回另一个承诺时)。实际上你根本不需要延期!
function fn1() {
return $("#result").animate({
width: 800,
height: 800
}, 5500).promise();
}
function fn2() {
return $("#result").animate({
opacity: 0.25
}, 2000).promise();
}
function fn3() {
$("#result").html("DONE!");
}
fn1().then(fn2).then(fn2);