简体   繁体   English

在for循环完成后,是否可以使用Deferred对象来创建回调?

[英]Is it possible to use a Deferred object in order to create a callback after a for loop has completed?

I have a for loop which fades in each li, what I want to do is wait until the very last li has fully faded in and then continue with the code similar to a callback but I'm unsure how to achieve this? 我有一个for循环,它在每个li中消失,我想要做的是等到最后一个li完全淡入然后继续代码类似于回调但是我不确定如何实现这个? I was thinking that I could possibly use a Deferred object? 我以为我可以使用Deferred对象?

JS JS

  var newArray = [3,2,6,4,0,1,5];
    for (var i = 0; i < newArray.length; i++) {
      var dfd = $.Deferred();
      $(this).eq(newArray[i]).fadeIn(i * 500);
      dfd.resolve();
      //.. continue with callback code??
    }

You can use $.when : by passing the Deferreds from all your fadeIn calls to it, you can register a callback to be executed only when all of them are done: 您可以使用$.when :通过将所有fadeIn调用中的Deferreds传递给它,您可以注册一个回调,只有在所有这些调用完成时才执行:

var deferreds = [];
for (var i = 0; i < newArray.length; i++) {
    var dfd = $(this).eq(newArray[i]).fadeIn(i * 500);
    deferreds.push(dfd);
}
$.when.apply($, deferreds).then(function() { ... });

Working example at jsFiddle . jsFiddle的工作示例。 Note that you can use the return value of fadeIn as a Deferred . 请注意,您可以使用fadeIn的返回值作为Deferred

Update: since you want each fadeIn to start only after the last one ended, Bergi's answer might be more appropriate. 更新:因为你希望每个fadeIn最后一个结束开始, 所以Bergi的答案可能更合适。 An alternative (simpler, IMHO) could be: 另一种选择(更简单,恕我直言)可能是:

var i = 0;
function f() {
    if ( i < newArray.length ) {
        $(this).eq(newArray[i]).fadeIn(i * 500, f);
        i++;
    } else {
        // Your "done" callback, if any
    }
}
f();

Working example . 工作实例 I stuck to your original code (each effect using a different duration), but if you want all them to have the same one, remove the i * and just use 500 . 我坚持你的原始代码(每个效果使用不同的持续时间),但如果你想让它们具有相同的一个,删除i *并使用500

I don't think Deferreds will be of great help here. 我不认为Deferreds会在这方面提供很大的帮助。 Surely, you can get a .promise() for every [effect] queue on jQuery instances, and because of that method you could even pass jQuery objects right into $.when , but I think a callback chain - and for successive animations you need some chain - can do it easier: 当然,你可以为jQuery实例上的每个[effect]队列获得一个.promise() ,并且因为你可以将jQuery对象直接传递到$.when ,但我认为是一个回调链 - 对于你需要的连续动画一些链 - 可以更容易:

function chainedFadeIn($el, order, callback) {
    if (!order.length)
        return callback();
    $el.eq(order.shift()).fadeIn(500, function() {
        chainedFadeIn($el, order, callback); // notice we removed the first element
    }); 
}
chainedFadeIn($(this), [3,2,6,4,0,1,5], function() {
    // do something
});

Alternative version with Promises: Promise的替代版本:

function getFadeInChain($el, order) {
    if (!order.length)
        return order; // or anything else
    return $el
      .eq(order.shift())
      .fadeIn(500)
      .promise()
      .then(getFadeInChain.bind(null, $el, order));
}
getFadeInChain($(this), [3,2,6,4,0,1,5]).done(function() {
    // do something
});

Demos at jsfiddle.net: callbacks , Deferred jsfiddle.net上的演示: 回调延期

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM