【问题标题】:Jquery Deferred and multiple deferred in chainJquery Deferred 和链中的多个延迟
【发布时间】:2015-11-13 06:58:10
【问题描述】:

请帮忙:

例如,我有 20 个超时,由 window.setTimeout 创建,我希望它们一个接一个地运行:

通话超时 1 => 完成通话超时 2 => 完成通话超时 3 后,依此类推。

一般有函数数组,超时次数不固定。

我的延迟函数

function someFunction(index) {
   console.log("someFunction called, index = " + index);
   var $deferred = $.Deferred();

   window.setTimeout(function () {
       $deferred.resolve();
   }, 2000);

   return $deferred.promise();
}

for循环

var $deferred;
$(someArray).each(function (index) {
    if (!$deferred) {
        $deferred = someFunction(index);
    } else {
        $deferred.then(function () {
            return someFunction(index);
        });
    }
});

所有其他的都立即运行而不在链中

【问题讨论】:

  • someArray变量有什么用?

标签: jquery settimeout jquery-deferred


【解决方案1】:

如果你想一个接一个地链接它们,你必须这样做:

var $deferred;
$(someArray).each(function (index) {
    if (!$deferred) {
        $deferred = someFunction(index);
    } else {
        $deferred = $deferred.then(function () {
            return someFunction(index);
        });
    }
});

您所做的是将所有 .then() 处理程序放在同一个 deferred 上,这将使它们全部并行运行,而不是串行运行。你需要的是 p.then(...).then(...).then(...) 的等价物。由于每个.then() 都会返回一个新的promise,因此您需要链接到链中的下一个链接。


您可能会发现这种设计模式更简单,因为使用异步操作按顺序迭代数组会生成一个 Promise:

someArray.reduce(function(p, item) {
    return p.then(function() {
        return someFunction(item);
    });
}, $.Deferred().resolve()).then(function() {
    // all done here
});

工作演示:http://jsfiddle.net/jfriend00/uusjs3mt/

【讨论】:

  • setTimeout 持续时间未按预期在.reduce() 版本中应用
  • 是的,在 console jsfiddle.net/59sn1u31 时是 1.7.2; 1.11.0jsfiddle.net/59sn1u31/1
  • 是的,试过.reduce() 版本console,所以使用 1.7.1;另见stackoverflow.com/questions/32790917/…
  • @guest271314 - 你发布了我不明白的神秘 cmets。如果您需要帮助,请使用词语来描述您所询问的内容或您需要帮助的其他内容。
  • @guest271314 - 如果你想使用可靠、可预测的 Promise,我建议只使用最新版本的 jQuery、支持 ES6 Promise 的浏览器或像 Bluebird 这样的 Promise 库。
【解决方案2】:

尝试使用$.queue()$.dequeue()$.map()

function someFunction(index) {
  console.log("someFunction called, index = " + index);
  var $deferred = $.Deferred();

  window.setTimeout(function() {
    $deferred.resolve();
  }, 2000);

  return $deferred.promise();
}

var someArray = [1, 2, 3, 4, 5];

$.queue(someArray, "dfd", $.map(someArray, function(value, index) {
  return function(next) {
    someFunction(index).then(next)
  }
}));
$.dequeue(someArray, "dfd");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

【讨论】:

    【解决方案3】:

    两种方法都有效:

    $.queue(someArray, "dfd", $.map(someArray, function(value, index) {
      return function(next) {
        someFunction(index).then(next)
      }
    }));
    $.dequeue(someArray, "dfd");
    

    someArray.reduce(function(p, item) {
        return p.then(function() {
            return someFunction(item);
        });
    }, $.Deferred().resolve()).then(function() {
        // all done here
    });
    

    【讨论】:

    • StackOverflow 上的协议不是发布您自己的答案,而只是复制其他人发布的信息。如果您的问题已得到解答,您可以通过单击该答案左侧的绿色复选标记来选择最佳答案,然后您可以对任何答案发表评论。一旦您获得更多声望点,您就可以投票任何对您有帮助的答案。
    猜你喜欢
    • 1970-01-01
    • 2017-03-17
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多