简体   繁体   中英

How to loop through an array in waiting a time between each item?

I have an array like this:

var items = [["text1", 3000],["text2",4000],["text3",1000]], ...a lot more here...; .

In the html side, we got <div id="d"></div>

Now, I want to print out " text1 " on the div after 3000 milliseconds, the PC will then wait for 4000 milliseconds before printing " text2 ", then it will print out " text3 " after 1000 milliseconds, so on until it finishes the loop.

I think we need to do with setInterval or something like that but it is too hard for me to think of it. Maybe a nested setInterval ??

So Given an 2-D array of text & millisecond-number, How to print each item out after a specified milliseconds?

Note: I need to print out in the right order of items , that is it will print out text1 first, then text2, then text3, ...

Edit

Finally found the solution

 var items = [["text1", 3000],["text2",4000],["text3",1000]]; var time=0; printElems(0); function printElems(i){ setTimeout(function(){ var elem=document.getElementById("d"); elem.innerHTML=items[i][0]; if(items[i+1]!=undefined){ printElems(i+1); } },items[i][1]); }
 <div id="d"></div>

This will do the trick. What I have done here is, just sum the times and make setTimeout calls based on the delay.This loops through the array in the given order.

Unfortunately, they will be printed from the shortest time to the longest time if you wrap a setTimeout (asynchronous) in a loop (synchronous).

To solve the problem you can use Promises.

Here is an implementation with jQuery.Deferred :

var dfd = $.Deferred().resolve();

items.forEach((item) => {
    dfd = dfd.then(() => print(item));
});

function print(item) {
    var dfd = $.Deferred();

    setTimeout(() => {
        $('#d').html(item[0]);
        dfd.resolve();
    }, item[1]);

    return dfd.promise();
}

DEMO

With promises, compactly:

function wait(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }

items.reduce((promise, [text, ms]) => 
    promise . then(() => wait(ms)) . then(() => console.log(text)),
  Promise.resolve());

With setTimeout , recursively:

function sequence(array) {
  if (!array.length) return;
  var elt = array.shift();
  setTimeout(() => {
    console.log(elt[0]);
    sequence(array);
  }, elt[1]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM