如何使用jQuery Deferred(何时/那么等等)来解决厄运的异步金字塔问题 [英] How to use jQuery Deferred (when/then, etc.) to fix asynchroneous pyramid of doom issue

查看:98
本文介绍了如何使用jQuery Deferred(何时/那么等等)来解决厄运的异步金字塔问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经困惑了很长时间,试图将我的头放在JavaScript promises上.我想修复代码中异步调用的一些问题,以消除它的失调.但是我很想请一位专家来帮助我,因为我已经浪费了很多时间.

I've been puzzling for quite a while trying to wrap my head around JavaScript promises. I want to fix some issues with asynchroneous calls in my code, to de-spagethise it. But I'd love for an expert to help me, because I've wasted quite some time already.

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

I want to use the jQuery Deferreds for it, since I'm using jQuery (v1.11) in my project already, and I don't want to add any more libraries (already have over 5). I read that the jQuery doesn't fully follow the Promises/A spec, but I figured it'd be good enough for my use case. I'll look at q.js or other libs later.

我试图创建一个简单的示例,并且我已经很熟悉JavaScript的异步行为,例如以下SO问题所示: setTimeout延迟不起作用

I was trying to create a simple example and I'm already familiar with the asynchroneous behaviour of JavaScript as exemplified by this SO question: setTimeout delay not working

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

I created a JS fiddle to solve that user's problem but using a 'pyramid of doom' construction: http://jsfiddle.net/bartvanderwal/31p0w02b/

现在,我想要一个很好的简单示例,说明如何使用Promises扁平化金字塔,并使用then()或类似方法链接方法:

Now I would like a nice bare-bones example of how to flatten this pyramid using Promises and chaining method calls using then()'s or something:

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

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

However I can't get it to work. My attempt so far is in this Fiddle: http://jsfiddle.net/bartvanderwal/vhwnj6dh/


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


Edit 20:58: Here is the now working fiddle thanks to (mainly) @Bergi: http://jsfiddle.net/bartvanderwal/h2gccsds/

推荐答案

但是我无法正常工作

But I can't get it to work

一些要点:

  • 不要使用deferreds数组,更不要使用全局数组!将其分解为单个步骤,并为每个步骤使用一个承诺.
  • 使用计数器值来解决承诺.许诺应始终代表(异步)结果.
  • 除非您需要等待多个承诺,否则不要使用$.when
  • then确实具有回调函数.您不得呼叫takeStep(),而应通过它.
  • don't use an array of deferreds, even less a global one! Break it into single steps, and use a single promise for each step.
  • use the counter value to resolve the promise. A promise should always represent an (async) result.
  • don't use $.when unless you need to wait for multiple promises
  • then does take a callback function. You must not call takeStep(), but pass it.

您可能还想看看此答案以了解经验法则,以熟悉诺言.

You also might want to have a look at this answer for rules-of-thumb to get familiar with promises.

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

这篇关于如何使用jQuery Deferred(何时/那么等等)来解决厄运的异步金字塔问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆