【问题标题】:How to use jQuery Deferred (when/then, etc.) to fix asynchroneous pyramid of doom issue如何使用 jQuery Deferred (when/then 等) 来修复异步金字塔的厄运问题
【发布时间】:2014-12-04 16:46:44
【问题描述】:

很长一段时间以来,我一直在费解 JavaScript 承诺。我想解决我的代码中异步调用的一些问题,以对其进行去页面化。但是我很想请一位专家来帮助我,因为我已经浪费了很多时间了。

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

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

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

现在我想要一个很好的简单示例,说明如何使用 Promises 和使用 then() 之类的链接方法调用来展平这个金字塔:

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

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


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

【问题讨论】:

    标签: javascript jquery promise settimeout jquery-deferred


    【解决方案1】:

    但我无法让它工作

    几点:

    • 不要使用deferreds 的数组,更不要使用全局数组!将其分解为单个步骤,并为每个步骤使用一个 Promise。
    • 使用计数器值来解决承诺。承诺应始终代表(异步)结果。
    • 不要使用$.when,除非你需要等待多个promise
    • then 确实有一个回调函数。你不能打电话给takeStep(),而是通过它。

    您可能还想查看this answer 的经验法则以熟悉 Promise。

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

    【讨论】:

    • 谢谢@Bergi。对于指针,虽然是延迟数组,但只是使东西正常工作的中间尝试,但都是好的。我将您的代码放入(工作)JSFiddle:http://jsfiddle.net/bartvanderwal/h2gccsds/
    • 谢谢,很高兴听到它有效 - 我没有努力测试它:-)
    • 它没有严格工作,就像'没有编译',因为缺少一些函数和常量(如stepTime),但它们只会分散答案。寻找编译代码的读者应该去 Fiddle :)。
    猜你喜欢
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    相关资源
    最近更新 更多