setInterval用于导致函数失败

时间:2012-09-13 21:04:01

标签: javascript jquery for-loop setinterval

我有两个功能

 function getImgStr(imgName){
        thisStr = '<img src="/_shared/img/discovery/200x100/'+imgName+'.jpg">';
        return thisStr;
    }
    function buildIt(imgSrc){
        console.log(imgSrc);
        $('#content').append('<div></div>');
        $('#content div:last').hide()
            .addClass('imgBox')
            .attr('id',imgSrc)
            .html(getImgStr(imgSrc))
            .slideDown(2000);
    }

我有一个我正在循环的数组

$(function(){
        for(i=0;i<=imgList.length-1;i++){
                buildIt(imgList[i]);
        }
    });

工作正常,没有问题。

但是当我尝试换行时,这是一个setInterval是barfs

$(function(){
        for(i=0;i<=imgList.length-1;i++){
            var loadIt = setInterval(function(){
                buildIt(imgList[i]);
            },1000);
        }
    });

当setInterval存在时,buildIt中的console.log是未定义的,所以我假设间隔以某种方式影响循环,但我不明白我做错了什么。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

根据您的说明:如果您想每秒一个接一个地加载图像,您可以执行类似的操作。你根本不需要循环。

var i = 0;
var id = setInterval(function() {
    if(i === imgList.length) {
        clearInterval(id);
    } else {
        buildIt(imgList[i++]);
    }
}, 1000)

这样做是将i的值初始化为0. i函数,与for循环中的i完全相同。它本质上是一个索引。然后,将变量id内的间隔值存储起来。这样,您可以保留对间隔的引用,以便在加载图像时可以清除它。

最后,在区间函数中,检查i是否等于图像列表中图像数的长度。如果是,我们知道我们已完成加载所有这些,所以我们清除间隔。否则,我们会将buildIt函数调用为与i的当前值对应的图像,并将i的值增加。

答案 1 :(得分:1)

使用fiddle

更新

   this.buildIt= function(imgSrc){
    console.log("test"+imgSrc)
    console.log(imgSrc.length)
        };

$(function(){ 
      var imgList=[
"test1","test2","test3","test4"
]
        for(i=0;i<=imgList.length;i++){

            var loadIt = setInterval(function(){
                this.buildIt(imgList);
            },1000,imgList);
        }
    });​

答案 2 :(得分:0)

UPDATE :我还不完全清楚OP正在尝试做什么,但我会根据我的理解在堆上找到另一个解决方案。您有N个图像,并且您希望每秒按顺序更新这些图像。为此,您必须将setTimeoutsetInterval合并。 setTimeout将错开图像的更新,setInterval将导致每个图像依次更新。以下是它的外观:

function start() {
    var nImages = 5;
    for( i=0; i<nImages; i++ ) {
        (function(j){
            setTimeout( function() {
                buildIt(j);
                intervals.push(
                    setInterval( function() {
                        buildIt(j);
                    }, 1000*nImages )
                );
            }, j*1000 );
        })(i);
    }
}

function stop() {
    for( i in intervals ) {
        clearInterval( intervals[i] );
    }
}

这是一个证明这一点的jsFiddle:http://jsfiddle.net/FtCCs/

这是我之前的回答: Vivin走在正确的轨道上,但他的解决方案也无法正常工作,因为它只是将封闭问题推向了堆栈。但是,他在一个方面是正确的:您的buildIt函数调用没有获得您期望的索引,但是所有索引都相同。你需要做的是:

$(function(){
    for(i=0;i<=imgList.length-1;i++){
        (function(j){
            var loadIt = setInterval(function(){
                buildIt(imgList[j]);
            },1000);
        })(i);
    }
});

要清楚地了解正在发生的事情,请考虑以下示例:

HTML:

<div id="wrong1">Wrong:<br /></div>
<div id="wrong2">Wrong:<br /></div>
<div id="wrong3">Wrong:<br /></div>
<div id="right">Right:<br /></div>

jQuery的:

// won't work:
for(var i=0;i<5;i++) {
    setTimeout( function() { $('#wrong1').append(i+'<br />'); }, 500 );
}

// won't work:
for(var i=0;i<5;i++) {
    var j = i;
    setTimeout( function() { $('#wrong2').append(j+'<br />'); }, 500 );
}

// won't work:
for(var i=0;i<5;i++) {
    setTimeout( function() { (function(j){ $('#wrong3').append(j+'<br />'); })(i) }, 500 );
}

// works!
for(var i=0;i<5;i++) {
    (function(j){
        setTimeout( function() { $('#right').append(j+'<br />'); }, 500 );
    })(i);
}

我在这里设置了一个JsFiddle来演示:http://jsfiddle.net/k3RJL/1/

在所有“错误”示例中,变量ij是一个闭包,但到setTimeout中的函数执行时,该值已更改为封闭中的最终值,所以它们都是一样的。请注意wrong2中的差异:它查看j循环中定义的变量for,因此它永远不会收到i的最终值,这就是为什么它停在4点。