首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >控制流程与承诺

控制流程与承诺
EN

Stack Overflow用户
提问于 2015-06-05 16:39:12
回答 2查看 464关注 0票数 1

我在html里有很多div。每个div包含动画或一些js代码,这些代码仅在该div可见时调用:

代码语言:javascript
运行
复制
<button id='start' class='start'>Start</button> 

<div class="step1 later">
  <div class='red later'>Show first</div>
  <div class='aqua later'>Show later</div>
</div>

<div class="step2 later">
  <div class='green later'>Show together</div>
  <div class='yellow later'>Show together</div>
</div>

我的目标是用div类显示step1,调用一些js,然后显示step2等等。看上去像滑块。在这个例子中,我想要显示step1,然后用red类显示div,延迟之后我想显示aqua。接下来,我们将进入step2并立即显示两个div:yellowgreen。我已经决定使用承诺(Q.js)来实现这一目标。这是我的密码:

代码语言:javascript
运行
复制
$(function () {
  var currentStep = 1,
      handlers = {};  

  $('#start').click(function() {
    for(var i = 0; i < 2; i++) {          
      showStep(currentStep + i);
    }     
  });      

  function showStep(step) {
    var name = 'step' + step;
    $('.' + name).show();

    handlers[name]();
  }


  handlers.step1 = function() {
    Q().then(function() {
       $('.notification').html('Step1 started');
    })
    .delay(2000)
    .then(function() {
       showElem('red');     
    })
    .delay(2000)
    .then(function() {
       showElem('aqua');     
    });
  };

    handlers.step2 = function() {
    Q().then(function() {
       $('.notification').append('Step2 started');
    })
    .delay(2000)
    .then(function() {
       showElem('green'); 
       showElem('yellow'); 
    });    
  };

  function showElem(classSelector) {
    $('.' + classSelector).fadeIn(100);
  }

});

除了一件事外,所有的动画和延迟作品都能找到。当一个步骤完成时,我的代码不会等待,处理程序几乎同时启动。

演示:JSBIN

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-05 23:58:14

使用q来调度jQuery操作是非常不常规的。通过明智地使用它的.delay().promise()方法,jQuery能够很好地独立完成这项工作。

在以下代码重写中:

  • 从各种函数返回承诺,以允许链接。
  • 主(开始)例程是一个简单的两步.then()链。
  • showElem()showStep()是不必要的并且消失了
  • handlers是作为一个对象文字编写的。
代码语言:javascript
运行
复制
jQuery(function ($) {
    var handlers = {
        'step1': function() {
            $('.notification').html('<div>Step1 started</div>');
            return $(".step1").show(0).delay(2000).promise().then(function() {
                return $('.red').fadeIn(100).delay(2000).promise();
            }).then(function() {
                return $('.aqua').fadeIn(100).promise();
            });
        },
        'step2': function() {
            $('.notification').append('<div>Step2 started</div>');
            return $(".step2").show(0).delay(2000).promise().then(function() {
                return $('.green, .yellow').fadeIn(100);
            });
        }
    };

    $('#start').click(function() {
        handlers.step1().then(handlers.step2);
    });
});

演示

编辑

对于大量的处理程序,您可以按照以下方式长出"start“例程:

代码语言:javascript
运行
复制
$('#start').click(function() {
    handlers.step1()
    .then(handlers.step2)
    .then(handlers.step3)
    .then(handlers.step4)
    .then(handlers.step5)
    .then(handlers.step6)
    ...
    ;
});

但是,这可能需要大量输入,并且不能满足不同数量的处理程序的需要。

解决方案相当简单。

首先,将handlers写为数组,而不是对象。

代码语言:javascript
运行
复制
var handlers = [
    //step 0
    function() {
        $('.notification').html('<div>Step1 started</div>');
        return $(".step1").show(0).delay(2000).promise().then(function() {
            return $('.red').fadeIn(100).delay(2000).promise();
        }).then(function() {
            return $('.aqua').fadeIn(100).promise();
        });
    },
    //step 1
    function() {
        $('.notification').append('<div>Step2 started</div>');
        return $(".step2").show(0).delay(2000).promise().then(function() {
            return $('.green, .yellow').fadeIn(100);
        });
    },
    //step 2,
    ...
    //step 3,
    ...
];

现在,您可以使用array方法.reduce()扫描数组,构建承诺链:

代码语言:javascript
运行
复制
$('#start').click(function() {
    handlers.reduce(function(promise, handler) {
        return promise.then(handler);
    }, $.when());
});

在这里,$.when()是一个解决的“种子”承诺,使链启动。

演示

票数 2
EN

Stack Overflow用户

发布于 2015-06-05 17:13:05

问题在于您的初始" for“循环,在该循环中,您在一次执行中执行了所有"showStep”,而无需等待承诺。

相反,你可以这样做:

代码语言:javascript
运行
复制
$('#start').click(function() {
  showStep(1);
});

function showStep(step) {
  var name = 'step' + step;
  $('.' + name).show();
  handlers[name]().then(function() {
    if (step < 2) {
      showStep(step+1);
    }
  });
}

让你的操纵者还承诺。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30671630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档