如何在数组中循环,等待每个项目之间的时间

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

本文关键字:项目 之间 时间 等待 数组 循环      更新时间:2023-09-26

我有一个这样的数组:

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

在html端,我们得到了<div id="d"></div>

现在,我想在3000毫秒后在div上打印出"text1",然后PC会等待4000毫秒再打印"text2",然后在1000毫秒后打印出"text3,以此类推,直到它完成循环。

我认为我们需要使用setInterval或类似的东西,但我想起来太难了。也许是嵌套的setInterval??

所以给定一个2-D的文本数组&毫秒数,如何在指定的毫秒后打印出每个项目

注意:我需要按照items的正确顺序打印出来,也就是说,它会先打印出text1,然后打印出text2,再打印出text3。。。

编辑

最终找到解决方案

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>

这就行了。我在这里所做的是,只需将时间相加,并根据延迟进行setTimeout调用。这将按给定的顺序在数组中循环。

不幸的是,如果将setTimeout(异步)封装在循环(同步)中,它们将从最短时间打印到最长时间。

为了解决这个问题,你可以使用Promises。

下面是jQuery的一个实现。递延:

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

有承诺,紧凑:

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());

使用setTimeout,递归:

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