Deferred()只使2个函数异步

时间:2017-03-16 00:52:09

标签: javascript jquery asynchronous promise jquery-deferred

小提琴: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()只是在没有等待的情况下开始。

3 个答案:

答案 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;
&#13;
&#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);