【问题标题】:Promise and deferred objects承诺和延迟对象
【发布时间】:2014-06-07 08:28:27
【问题描述】:

我从这里的一个非常好的答案中获得了以下内容,将两个建议的方法拼接在一起,但我看不出如何让代码正常工作。

var animals = ['mouse', 'newt', 'shrew', 'grasshopper', 'frog', 'hedgehog'];

$('#s1text1').delay(dur).fadeOut(dur).promise()
.then(function() {
    return $('#s1text2').fadeIn(dur).promise();
})
.then(function() {
    var p = new $.Deferred().resolve();
    return $.each(animals, function(i, animal) {
        p = p.then(function() {
            return $('.' + animal).fadeIn(defaultDur, function() {
                animateAnimalGroup(animal);
            }).promise();
        });
    })
    .then(function() {
        return $('#s1text2').fadeOut(dur).promise();
    })
    .then(function() {
        return $('#s1text3').fadeIn(dur).promise();
    })
    .then(function() {
        return $('#s1text4').fadeIn(dur).promise();
    });

任何帮助/建议将不胜感激。如果有人知道的话,关于这方面的一个很好的教程/文章也会非常有用,我已经阅读了一些内容,但我正在努力理解它。

【问题讨论】:

  • 实际描述问题会很有帮助。什么是不工作的,它应该如何工作?
  • 你在哪里关闭 p = p.then 中的 .then
  • var p = new $.Deferred().resolve(); 的意义何在?为什么要创建一个 deferred 并立即解决它?为什么不创建一个延迟的,然后再解决呢?或者更好的是,当您可以使用 jQuery 动画中的 Promise 时,为什么还要创建自己的?
  • @jfriend00 为了得到一个空的已解决承诺,以后用于排队操作。

标签: javascript jquery promise deferred


【解决方案1】:

你不想返回$.each的结果,你想返回你在循环中积累的ppromise。此外,它缺少右括号:

.then(function() {
    var p = new $.Deferred().resolve();
    $.each(animals, function(i, animal) {
        p = p.then(function() {
            …
        });
    })
    return p;
})
.then(…)

【讨论】:

    【解决方案2】:

    Bigwigal,您可能对涉及 array.reduce() 的替代方法感兴趣,以构建您的 .then() 链,而无需显式循环或显式分配/重新分配生成的 Promise。

    //Data
    var animals = ['mouse', 'newt', 'shrew', 'grasshopper', 'frog', 'hedgehog'],
        fades1 = [
            {id:'s1text1', delay:dur, action:'fadeOut'},
            {id:'s1text2', delay:0, action:'fadeIn'}
        ],
        fades2 = [
            {id:'s1text2', delay:0, action:'fadeOut'},
            {id:'s1text3', delay:0, action:'fadeIn'},
            {id:'s1text4', delay:0, action:'fadeIn'}
        ];
    
    //Phase 1 (initial fades)
    fades1.reduce(function(promise, item) {
        return promise.then(function() {
            return $('#' + item.id).delay(item.delay)[item.action](dur).promise();
        });
    }, $.when()).then(function() {
        //Phase 2 (animal fades)
        return animals.reduce(function(promise, animal) {
            return promise.then(function() {
                return $('.' + animal).fadeIn(defaultDur).promise().then(function() {
                    return animateAnimalGroup(animal);//you probably want a return here but not necessarily, depending on the visual effect you want.
                });
            });
        }, $.when());
    }).then(function() {
        //Phase 3 (final fades)
        return fades2.reduce(function(promise, item) {
            return promise.then(function() {
                return $('#' + item.id).delay(item.delay)[item.action](dur).promise();
            });
        }, $.when());
    });
    

    您现在拥有的是硬编码的通用三阶段动画模式,其细节是数据驱动。要更改细节,只需修改数组animalsfades1fades2

    这种方法可能很有用,与其说是最终结果,不如说是在开发过程中,您可能会在满意之前改变主意十几次。

    您可能更进一步,用一个数组和一个.reduce() 完成整个事情,但数据结构和代码可能会变得笨拙。

    我同意.reduce() 模式并不是这个星球上最易读的模式,但它非常值得克服学习它的痛苦障碍(就像我最近才这样做的那样)。

    【讨论】:

    • 感谢您花时间解释这一点,我真的很感激。我绝对可以看到这种方法的优势。
    • 我只是想投票赞成,但不幸的是我没有代表。再次感谢,非常有用。
    • Bigwigal,StackOverflow 中有一些废话。天知道为什么你需要代表才能投票。当您获得更多积分时,您可以稍后再回来。
    猜你喜欢
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2015-03-27
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多