如何使用jQuery Deferred(何时/然后等)来修复末日问题的异步金字塔

How to use jQuery Deferred (when/then, etc.) to fix asynchroneous pyramid of doom issue

本文关键字:末日 问题 金字塔 异步 Deferred jQuery 何使用 何时 然后      更新时间:2023-09-26

我一直在困惑一段时间,试图围绕JavaScript的承诺。我想修复代码中异步调用的一些问题,以取消 spagethise。但我希望有一位专家来帮助我,因为我已经浪费了相当多的时间。

我想使用它的jQuery Deferreds,因为我已经在项目中使用了jQuery(v1.11(,并且我不想添加更多的库(已经有超过5个(。我读到jQuery并不完全遵循Promises/A规范,但我认为它对于我的用例来说已经足够了。我稍后会看 q.js 或其他库。

我试图创建一个简单的示例,我已经熟悉JavaScript的异步行为,如这个SO问题所示:设置超时延迟不起作用

我创建了一个JS小提琴来解决该用户的问题,但使用了"厄运金字塔"结构:http://jsfiddle.net/bartvanderwal/31p0w02b/

现在我想要一个很好的简单示例,说明如何使用 Promise 和使用 then(( 或其他东西链接方法调用来展平这个金字塔:

$.when(takeStep())
  .then(takeStep())
  .then(takeStep())
  .then(takeStep())..

但是我无法让它工作。到目前为止,我的尝试是在这个小提琴中:http://jsfiddle.net/bartvanderwal/vhwnj6dh/


编辑20:58:这是现在工作的小提琴,这要归功于(主要(@Bergi:http://jsfiddle.net/bartvanderwal/h2gccsds/

但我无法让它工作

几点:

  • 不要使用deferreds数组,更不要使用全局数组!将其分解为单个步骤,并对每个步骤使用单个承诺。
  • 使用计数器值解析承诺。承诺应始终表示(异步(结果。
  • 不要使用$.when,除非你需要等待多个承诺
  • then确实采用回调函数。你不能叫takeStep(),而是通过它。

您可能还想看看这个答案的经验法则,以熟悉承诺。

// the most generic function that only waits and returns a promise
function wait(t, v) {
    var d = new $.Deferred();
    setTimeout(function() {
        d.resolve(v);
    }, t);
    return d.promise();
}
// logs the value and returns the next number
function markStep(nr) {
    log('step ' + cntr + ': ' + getCurrentTime() );
    return nr+1;
}
// waits before logging and returns a promise for the next number
function takeStep(nr) {
    return wait(stepTime, nr).then(markStep);
}
takeStep(0)
.then(takeStep)
.then(takeStep)
.then(takeStep)
.then(takeStep)
.done(function(nr) {
    log('done (' + getCurrentTime() + ')');
});