javascript - for循环中回调函数没有执行,如何让他执行?
天蓬老师
天蓬老师 2017-04-11 11:13:15
[JavaScript讨论组]

我想利用jquery循环执行动画,让动画先淡进,然后移动淡出,一开始我是一个一个写的,后来想利用for循环一步到位,发现用了for循环之后,动画只执行淡进,淡进完的回调函数没有执行

function Banner(wrap,li,showTime,hideTime){
    this.wrap = wrap;
    this.li = li;
    this.showTime = showTime;//一个数字
    this.hideTime = hideTime;一个数字
    this.DELY = hideTime - 1500;
}
Banner.prototype.init = function(){
    // setInterval(function(){
    var that = this; 
    that.cyclePlay(that,this.li.length);
    setInterval(function(){
        that.cyclePlay(that,that.li.length);
    },that.hideTime*that.li.length);
}
Banner.prototype.cyclePlay = function(that,length){
//    var length = this.li.length;
    var oldRight = '';
   //问题代码!!!
    for(var i = 0; i < length;i++){
        $(that.li[i]).children().delay(that.DELY*i).animate({
        opacity: '1'
    },that.showTime,function(){
            oldRight = $(that.li[i]).children().css('right');
            $(that.li[i]).children().animate({
            right: '450px',
            opacity: '0'
        },that.hideTime,function(){
            $(that.li[i]).children().css('right',oldRight);
        });
            });
    }
//for循环的内容原本我是这样执行的,这样是成功执行了。
$(that.li[0]).children().animate({
        opacity: '1'
    },that.showTime,function(){
            oldRight = $(that.li[0]).children().css('right');
            $(that.li[0]).children().animate({
            right: '450px',
            opacity: '0'
        },that.hideTime,function(){
            $(that.li[0]).children().css('right',oldRight);
        });
            });
    $(that.li[1]).children().delay(that.DELY).animate({
        opacity: '1'
    },that.showTime,function(){
            oldRight = $(that.li[1]).children().css('right');
            $(that.li[1]).children().animate({
            right: '450px',
            opacity: '0'
        },that.hideTime,function(){
            $(that.li[1]).children().css('right',oldRight);
        });
            });
    $(that.li[2]).children().delay(that.DELY*2).animate({
        opacity: '1'
    },that.showTime,function(){
            oldRight = $(that.li[2]).children().css('right');
            $(that.li[2]).children().animate({
            right: '450px',
            opacity: '0'
        },that.hideTime,function(){
            $(that.li[2]).children().css('right',oldRight);
        });
            });
    $(that.li[3]).children().delay(that.DELY*3).animate({
        opacity: '1'
    },that.showTime,function(){
            oldRight = $(that.li[1]).children().css('right');
            $(that.li[3]).children().animate({
            right: '450px',
            opacity: '0'
        },that.hideTime,function(){
            $(that.li[3]).children().css('right',oldRight);
        });
            });
    $(that.li[4]).children().delay(that.DELY*4).animate({
        opacity: '1'
    },that.showTime,function(){
            oldRight = $(that.li[1]).children().css('right');
            $(that.li[4]).children().animate({
            right: '450px',
            opacity: '0'
        },that.hideTime,function(){
            $(that.li[4]).children().css('right',oldRight);
        });
            });
}

后来我把回调函数取消了解决了这个问题,代码为

for(var i = 0; i < length;i++){
        $(that.li[i]).children().delay(that.DELY*i).animate({
        opacity: '1'
    },that.showTime);
            oldRight = $(that.li[i]).children().css('right');
            $(that.li[i]).children().animate({
            right: '450px',
            opacity: '0'
        },that.hideTime);
            $(that.li[i]).children().animate({
                right: oldRight,
            },1);
    }

可是我对这些还不是很理解,之前为什么回调函数没有执行

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(1)
怪我咯

楼主遇到的是一个典型的 for 循环和异步调用的问题,因为在JS是单线程运行的,所有异步操作都要等同步操作执行完毕后再执行,所以等到异步执行的时候已经是for循环结束到底的i了,然而此时的i等于数组的长度,拿不到任何一个节点(0 到 length-1)才能拿到节点,所以后续的操作也没有效果。

我们把这个问题抽象一下

for (var i = 0; i < 6; i++) {
    // do 同步执行,里面的 i 是 0 
    do(i).then(function() {
       // another 异步执行,此时 i 已经是循环后的6
        another(i)
    })
}

楼主如果想要验证的话,可以自己把两个地方的i console.log 出来看下便知。

怎么样解决这个问题呢?通常我们使用闭包保存变量的方式来解决。

for (var i = 0; i < 6; i++) {
    // 立即执行函数作闭包,保存变量i为index
    (function(index) {
        do(index).then(function() {
            another(index);
        })
    })(i)
}

这样,虽然 i 还是在一直变,但是我们利用闭包里的 index,保存住了当时的值,就不怕出现上面的情况了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号