最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Display array elements with delay - Stack Overflow

programmeradmin4浏览0评论

I have an arrays=[John; Alex; Mark], I wanna to show the elements of this array one by one by 3 second delay.

for (var i=0; i<=3; i++)
  {
     setTimeout(function(){x.innerHTML=s[i]},3000)
  }

It seems very simple problem, but I can't figure out.

I have an arrays=[John; Alex; Mark], I wanna to show the elements of this array one by one by 3 second delay.

for (var i=0; i<=3; i++)
  {
     setTimeout(function(){x.innerHTML=s[i]},3000)
  }

It seems very simple problem, but I can't figure out.

Share Improve this question edited Nov 27, 2017 at 13:28 Hassan Imam 22.5k6 gold badges44 silver badges52 bronze badges asked Apr 3, 2013 at 13:19 user2240469user2240469 531 gold badge1 silver badge6 bronze badges 7
  • 2 (at least) three errors in four lines of code... – Alnitak Commented Apr 3, 2013 at 13:21
  • Did you look at the console in the browser for error messages? – epascarello Commented Apr 3, 2013 at 13:22
  • 1 ok, make that five errors... – Alnitak Commented Apr 3, 2013 at 13:31
  • possible duplicate of Javascript SetTimeout and Loops – Denys Séguret Commented Apr 3, 2013 at 13:37
  • Note that I voted as duplicate for the 2 main errors but Alnitak found other problems (which should have been found by OP with a little care). This question shouldn't be deleted thus in my opinion. – Denys Séguret Commented Apr 3, 2013 at 13:38
 |  Show 2 more comments

9 Answers 9

Reset to default 13
  1. your loop runs four times, not three
  2. setTimeout starts with a lower case s
  3. your delay should be 3000 for 3 seconds, not 2000
  4. your delay should be 3000 * i, not 3000 or they'll all fire at once
  5. you can't use loop variables inside an asynchronous callback without special precautions - the callbacks will all see the last value assigned to i, not the values it had as you went through the loop.

This works, and completely avoids the loop variable issue:

var s = ['John', 'Mark', 'Alex'];
var i = 0;

(function loop() {
    x.innerHTML = s[i];
    if (++i < s.length) {
        setTimeout(loop, 3000);  // call myself in 3 seconds time if required
    }
})();      // above function expression is called immediately to start it off

Note how it uses "pseudo-recursion" to trigger the next iteration 3000ms after the completion of the previous iteration. This is preferable to having n outstanding timers all waiting at the same time.

See http://jsfiddle.net/alnitak/mHQVz/

http://jsfiddle.net/rlemon/mHQVz/1/

I got to tinkering... albeit this is probably not the best solution it was fun.

var x = document.getElementById('x'),
    s = ['John', 'Mark', 'Alex'];

(function loop() {
    s.length && (x.innerHTML = s.shift(), setTimeout(loop, 3000));
})();

Alnitak's solution is alot better. However they both would work (his is just more readable and less hacky also does not destroy the array).

this will also help:

const fruits = ['apple', 'banana', 'mango', 'guava'];
let index = 0;
const primtMe = (value, i) => {
    if (i < fruits.length) {
        setTimeout(() => {
            console.log(i + ' value = ' + value)
            primtMe(fruits[i + 1], i + 1)
        }, 3000);
    } else {
        return;
    }
}

primtMe(fruits[index], index)

Try

var s=['John', 'Alex', 'Mark'];
var x = document.getElementById('x');

function display(i){
    if(i >= s.length){
        i = 0;
    }

    x.innerHTML = s[i];
    setTimeout(function(){
       display(i + 1)
    }, 2000)
}

display(0)

Demo: Fiddle

If you do not use closure, you will end up with i being undefined. This is because in each iteration you are overriding what i is. By the time it finishes, it will be undefined. Using a closure will preserve i.

On another note, it's kind of pointless to hard code in values (i.e. i<3) when you can just check for length. This way, if s ever changes, you for loop will still grab everything.

var s = ['john','mark','brian'];
for (var i = 0; i < s.length; i++) {
    (function(i) {
        setTimeout(function() {
            x.innerHTML = s[i];
        }, 3000*(i+1));
    })(i);
}

Your code won't work, since you set four timeouts of 2000 milliseconds (i.e. 2 seconds) at a time. You'd better use closure that sets three timeouts (by number of elements in array) with 3000 milliseconds of delay. It can be done with the following code (note that setTimeout is written from the small letter):

var s = ["John", "Alex", "Mark"];
for (var i = 0; i < s.length; i++) {
    (function(i) {
        setTimeout(function() {
            x.innerHTML = s[i];
        }, 3000 * i);
    })(i);
}

DEMO: http://jsfiddle.net/6Ne6z/

You can use setInterval to show elements one by one after 3 seconds delay:

s=["John", "Alex", "Mark"];

var i = 0;
var id = setInterval(function(){                
            if(i > s.length) {                  
                clearInterval(id);                  
            }
            else{
                console.log(s[i++]);
            }
}, 3000);

Try this without pseudo-recursion

var arr = [10,20,30,40]; // your array
var i = 0;
var interval = 2000 // 2 sec, you can add your time required
function callInterval() {
// set a variable for setInterval
	var time = setInterval(()=>{
		console.log('['+arr[i]+','+i+']');
		i++; 
		if(i==arr.length){
			this.clearInterval(time);// clear the interval after the index
		}
		}, interval);
}

callInterval();

I solved this problem by using setInterval. Here is my solution:

function delayPrint(arr, delay) {
    let index = -1;

    const interval = setInterval(function () {
        if (++index === arr.length) {
            clearInterval(interval);
            return;
        }

        console.log(arr[index]);
    }, delay);
}

let s = ['John', 'Alex', 'Mark'];

delayPrint(s, 3000);

// output:
// John after 3s
// Alex after 3s
// Mark after 3s

发布评论

评论列表(0)

  1. 暂无评论