首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何减少javascript/jquery中的嵌套回调

如何减少javascript/jquery中的嵌套回调
EN

Stack Overflow用户
提问于 2017-04-27 17:24:00
回答 4查看 555关注 0票数 7

我的任务是重写这个可怕的代码,这意味着在地图上的逐层褪色(它们都是透明的pngs)在网页上。它需要在一个序列中操作,然后循环回没有可见层的起始位置,然后一次回退一层。这个序列应该永远重复。

我不太确定在javascript中最推荐的方法是什么,并且感兴趣的是堆栈溢出必须说什么。

一定有比这更好的方法!我对任何方法的利弊都感兴趣。

代码语言:javascript
复制
setInterval(function(){
    $("#layer-1").fadeIn(1000, function() {
      $("#layer-2").fadeIn(1000, function() {
        $("#layer-3").fadeIn(1000, function() {
          $("#layer-4").fadeIn(1000, function() {
            $("#layer-5").fadeIn(1000, function() {
              $("#layer-6").fadeIn(1000, function() {
                $("#layer-7").fadeIn(1000, function() {
                  $("#layer-8").fadeIn(1000, function() {
                    // pause for 2 seconds, then reset and hide all layers:
                    $("#home-map .layer").delay(2000).fadeOut();
                  });
                });
              });
            });
          });
        });
      });
    });
  }, 10000)

编辑:我认为这与其他答案不同的原因是,我试图在一个无限循环中设置一些东西,并将动画链接起来。在javascript中有很多解决回调地狱的方法,这是一个非常常见的症结所在,因此毫无疑问也会有类似的问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-27 17:32:28

接受挑战..。使用递归方法。

代码语言:javascript
复制
(function main(index){
   if(index >= 9){
     return $.when($("#home-map .layer").delay(2000).fadeOut()).then(function(){
         main(1); //restart
     });
   }
  $("#layer-"+index).fadeIn(1000, function(){
         main(index+1);
  });
 })(1);

http://jsbin.com/rurokipipi/1/edit?output

票数 5
EN

Stack Overflow用户

发布于 2017-04-27 17:42:44

通过使用异步等待+承诺

如果你在动画之后打电话给.promise(),你会得到回报的。多亏了它,你才能等待它完成

代码语言:javascript
复制
async function animate() {
    await $("#layer-1").fadeIn(1000).promise()
    await $("#layer-2").fadeIn(1000).promise()
    await $("#layer-3").fadeIn(1000).promise()
    await $("#layer-4").fadeIn(1000).promise()
    await $("#layer-5").fadeIn(1000).promise()
    await $("#layer-6").fadeIn(1000).promise()
    await $("#layer-7").fadeIn(1000).promise()
    await $("#layer-8").fadeIn(1000).promise()
    // pause for 2 seconds, then reset and hide all layers:
    await $("#home-map .layer").delay(2000).fadeOut().promise();
}

const loop = () => animate().then(loop)
loop()

从这个角度来看,for循环非常适合。

代码语言:javascript
复制
async function animate() {
    for (let i = 1; i < 9; i++)
        await $(`#layer-${i}`).fadeIn(1000).promise()

    // pause for 2 seconds, then reset and hide all layers:
    await $("#home-map .layer").delay(2000).fadeOut();
}

这在最近的浏览器中才是可能的。

如果你想的话,它可以变得更动态。

代码语言:javascript
复制
for (let layer of $("#home-map .layer"))
    await $(layer).fadeIn(1000).promise()

这里有一个es5选择了相同的问题,但是使用了reduce承诺

代码语言:javascript
复制
function animate() {
  $(".layer").toArray().reduce(function(prev, elm){
    return prev.then(function(){
      return $(elm).fadeIn(1000).promise();
    })
  }, Promise.resolve()).then(function(){
    // do the master
    $(".masterLayer").delay(2000).fadeOut();
  })
}

animate()
代码语言:javascript
复制
.layer {
  display: none;
}
代码语言:javascript
复制
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="masterLayer">
  <div class="layer">layer 1</div>
  <div class="layer">layer 2</div>
  <div class="layer">layer 3</div>
  <div class="layer">layer 4</div>
  <div class="layer">layer 5</div>
  <div class="layer">layer 6</div>
</div>

票数 7
EN

Stack Overflow用户

发布于 2017-04-27 17:41:59

代码语言:javascript
复制
var MAX_LAYER_NUMBER        = 8;
var LAYER_FADE_IN_DURATION  = 1000;
var LAYER_FADE_OUT_DURATION = 1000;
var LAYER_FADE_IN_OUT_DELAY = 2000;

function fadeInLayer(layerNumber, done) {
  if (layerNumber <= MAX_LAYER_NUMBER) {
    $('#layer-' + layerNumber).stop(true, true).fadeIn(LAYER_FADE_IN_DURATION, function() {
      done(layerNumber);
      fadeInLayer(layerNumber + 1, done);
    });
  }
}

function fadeInOutLayers() {
  fadeInLayer(1, function(layerNumber) {
    if (layerNumber === MAX_LAYER_NUMBER) {
      $(".layer").delay(LAYER_FADE_IN_OUT_DELAY).fadeOut(LAYER_FADE_OUT_DURATION);
    }
  });
}


$(function() {
  fadeInOutLayers();
  setInterval(fadeInOutLayers, LAYER_FADE_IN_DURATION * MAX_LAYER_NUMBER + LAYER_FADE_IN_OUT_DELAY + LAYER_FADE_OUT_DURATION)
});
代码语言:javascript
复制
.layer {
  display: none;
}
代码语言:javascript
复制
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="layer-1" class="layer">layer-1</div>
<div id="layer-2" class="layer">layer-2</div>
<div id="layer-3" class="layer">layer-3</div>
<div id="layer-4" class="layer">layer-4</div>
<div id="layer-5" class="layer">layer-5</div>
<div id="layer-6" class="layer">layer-6</div>
<div id="layer-7" class="layer">layer-7</div>
<div id="layer-8" class="layer">layer-8</div>

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

https://stackoverflow.com/questions/43664279

复制
相关文章

相似问题

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