如何使用jQuery延迟(当/当等)来修复厄运问题的异步金字塔

时间:2014-12-04 16:46:44

标签: javascript jquery promise settimeout jquery-deferred

我一直困惑地试图绕过JavaScript承诺。我想在我的代码中解决一些异步调用的问题,以解决它的问题。但我很乐意帮助一位专家帮助我,因为我已经浪费了很多时间。

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

我试图创建一个简单的示例,我已经熟悉JavaScript的异步行为,例如这个SO问题: setTimeout delay not working

我创建了一个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/

1 个答案:

答案 0 :(得分:2)

  

但我无法让它工作

有些观点:

  • 不要使用deferreds数组,更不要使用全局数组!将其分解为单个步骤,并为每个步骤使用单个承诺。
  • 使用计数器值来解决承诺。承诺应始终代表(异步)结果。
  • 除非您需要等待多个承诺,否则不要使用$.when
  • then确实接受了回调功能。您不得致电takeStep(),而是通过。

您还可以查看this answer的经验法则,以熟悉承诺。

// 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() + ')');
});