如何在每个项目之间等待一段时间循环数组?

时间:2016-04-16 01:39:00

标签: javascript loops asynchronous promise

我有一个这样的数组:

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

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

现在,我要打印出&#34; text1 &#34;在3000毫秒后的div上,PC将在打印前等待4000毫秒&#34; text2 &#34;然后它将打印出来&#34; text3 &#34;在1000毫秒之后,依此类推,直到它完成循环。

我认为我们需要使用setInterval或类似的东西,但我很难想到它。也许是嵌套的 setInterval ??

所以给定一个二维数组文本&amp;毫秒数,如何在指定的毫秒后打印出每个项目?

注意:我需要按照items的正确顺序打印出来,就是先打印出text1,然后是text2,然后是text3,...

3 个答案:

答案 0 :(得分:1)

修改

终于找到了解决方案

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 调用。这会以给定的顺序循环遍历数组。

答案 1 :(得分:0)

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

要解决此问题,您可以使用Promises。

以下是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

答案 2 :(得分:0)

承诺,紧凑:

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]);
}