如何解决几个deferred里面的`promise.then()`

时间:2017-03-09 09:56:20

标签: javascript jquery

我需要在promise.then()中运行几个并行函数 我尝试使用类似下面的代码,但它的工作不正确:

function fadeElement(selector){
        return function () {
            return $(selector).fadeOut(400).promise();
        }
}

function runParallel(owner, promises) {
    return function () {
        var differed = new $.Deferred();
        var resolveDiffered = function () { differed.resolve(); };
        $.when.apply(owner, promises).
            then(resolveDiffered);
        return differed.promise();
    }
}

FormInput.prototype.ReloadPage = function(){
    var firstOne = fadeElement('#element_Id_1');
    var firstTwo = fadeElement('#element_Id_2');
    var firstThree = fadeElement('#element_Id_3');

    var secondOne = fadeElement('#element_Id_4');

    var thirdOne = fadeElement('#element_Id_5');
    var thirdTwo = fadeElement('#element_Id_6');

    $.when(firstOne(), firstTwo(), firstThree())
    .then(secondOne)
    .then(
        runParallel(this, [thirdOne(), thirdTwo()])
    );
}

firstOnefirstTwofirstThreesecondOne运行时间不超过400毫秒。

thirdOnethirdTwo - 根本不运行。

我认为我在runParallel中犯了一个错误,但我有足够的知识来强调在哪里。我想是的,因为这段代码会起作用:

$.when(firstOne(), firstTwo(), firstThree())
.then(secondOne)
.then(thirdOne)
.then(thirdTwo);

1 个答案:

答案 0 :(得分:1)

问题在于,当您将这些功能传递给thirdOne时,您正在调用thirdTworunParallel(从而启动淡入淡出过程):

.then(
    runParallel(this, [thirdOne(), thirdTwo()])
);

相反,您应该删除最终的()并将函数传递给runParallel,这应该将每个方法映射到调用它的结果。更改每个承诺生成函数调用时的位置将允许延迟淡出过程,直到其他承诺完成之后:

function fadeElement(selector) {
  return function() {
    return $(selector).fadeOut(400).promise();
  }
}

function runParallel(owner, promises) {
  return function() {
    return $.when.apply(owner, promises.map($.call, $.call))
  }
}

FormInput.prototype.ReloadPage = function() {
  var firstOne = fadeElement('#element_Id_1');
  var firstTwo = fadeElement('#element_Id_2');
  var firstThree = fadeElement('#element_Id_3');

  var secondOne = fadeElement('#element_Id_4');

  var thirdOne = fadeElement('#element_Id_5');
  var thirdTwo = fadeElement('#element_Id_6');

  $.when(firstOne(), firstTwo(), firstThree())
    .then(secondOne)
    .then(
      runParallel(this, [thirdOne, thirdTwo])
    );
}


function FormInput () {

}

new FormInput().ReloadPage()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="element_Id_1">1</div>
<div id="element_Id_2">2</div>
<div id="element_Id_3">3</div>
<div id="element_Id_4">4</div>
<div id="element_Id_5">5</div>
<div id="element_Id_6">6</div>