javascript - for循环中回调函数没有执行,如何让他执行?

查看:153
本文介绍了javascript - for循环中回调函数没有执行,如何让他执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

我想利用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);
    }

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

解决方案

楼主遇到的是一个典型的 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,保存住了当时的值,就不怕出现上面的情况了。

这篇关于javascript - for循环中回调函数没有执行,如何让他执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆