我试图运行多个setInterval()
但我在执行此操作的异步方面遇到了问题。
这个例子与我试图实现的几乎相同:
var labels = ["Bacon", "Beer", "Steak"];
var second, timer;
labels.forEach(function(label){
second = 0;
timer = setInterval(function(){
console.log(label + ' is awesome ' + second);
if(second === 10) {
clearInterval(timer);
}
second++;
}, 1000);
});
由于setInterval是异步的,因此三个间隔并行运行并且正在弄乱间隔:
培根非常棒0
啤酒真棒1
牛排很棒2
啤酒很棒3
培根很棒4
牛排很棒5
培根非常棒6
啤酒很棒7
牛排很棒8
培根很棒9
啤酒很棒10
啤酒很棒11
培根非常棒12
啤酒很棒13
培根很棒14
培根非常棒15
啤酒很棒16
啤酒很棒17
培根很棒18
培根很棒19
啤酒很棒20
啤酒很棒21
培根很棒22
培根很棒23
...
我想知道如何强制执行某种队列,以便第一个间隔运行它,然后当10秒钟时,下一个setInterval被执行?
我已经快速尝试了async.js库,但我找不到合适的控制流程。
答案 0 :(得分:2)
这对我来说很适合练习一些OO风格的Javascript:)
function Timer(name) {
var self = this;
this.name = name;
this.count = 0;
this.x = setInterval(function () {
if (self.count++ == 9) {
clearInterval(self.x);
}
console.log(self.name + ' ' + self.count + ' is awesome');
}, 1000);
}
var labels = ["Bacon", "Beer", "Steak"];
labels.forEach(function (label) {
new Timer(label);
});
答案 1 :(得分:2)
我做了一个名为`callQueue'调用一个充满函数的数组按顺序调用一定次数
<强>用法强>
第一个参数是函数数组,第二个参数是它们应被调用的次数,第三个参数是调用之间的时间。
callQueue([
function () {
isAwesome('bacon');
},
function () {
isAwesome('beer');
},
function () {
isAwesome('steak');
}], 10, 1000);
功能
function callQueue(queue, times, timeBetween) {
var i = 0;
k = 0;
queue.forEach(function (func) {
for (k = 0; k < times; k += 1) {
alert(i * timeBetween);
i += 1;
setTimeout(func, (i * timeBetween));
}
});
};
答案 2 :(得分:2)
你可以例如在没有循环的情况下使用setTimeout
,并从函数中选择正确的标签。
var labels = ["Bacon", "Beer", "Steak"],
steps = 10,
total = 0,
step = 0,
sequence = 0,
label = labels [0];
(function fn (){
if (step === steps && sequence === labels.length - 1) {
return;
} else if(step === steps) {
label = labels [++sequence];
step = 0;
}
console.log(label + ' is awesome ' + total);
step++;
total++;
setTimeout (fn, 1000)
})();
或者例如保持循环并使用索引和步数作为超时乘数,以相应地延迟其他超时。
var labels = ["Bacon", "Beer", "Steak"],
steps = 10,
total = 0;
labels.forEach(function(label, index){
var step = 0;
setTimeout (function fn (){
if(step === steps) {
return;
}
console.log(label + ' is awesome ' + total);
step++;
total++;
setTimeout (fn, 1000)
},( (steps + 1)* index ) * 1000);
});
或者将setInterval
包裹在setTimeout
中。
var labels = ["Bacon", "Beer", "Steak"];
labels.forEach(function(label, index){
setTimeout (function () {
var second = 0;
var timer = setInterval(function(){
console.log(label + ' is awesome ' + second);
if(second === 10) {
clearInterval(timer);
}
second++;
}, 1000);
},index * 11 * 1000);
});
所有产品
Bacon is awesome 0
Bacon is awesome 1
Bacon is awesome 2
Bacon is awesome 3
Bacon is awesome 4
Bacon is awesome 5
Bacon is awesome 6
Bacon is awesome 7
Bacon is awesome 8
Bacon is awesome 9
Beer is awesome 0
Beer is awesome 1
Beer is awesome 2
Beer is awesome 3
...
答案 3 :(得分:0)
在您拨打setInterval
和setTimeout
之后,您已经掌握了浏览器;通过的时间并不保证是准确的,并且执行多个回调的顺序并不保证是准确的 - 并且通常不会成为。
如果要强制执行顺序,使用setTimeout
代替setInterval
将使您有机会决定每次回调完成时会发生什么。
这是一个小提琴首先迭代培根,然后是啤酒,然后是牛排:http://jsfiddle.net/q96Vc/
这是一个一个接一个地显示每个标签,直到30秒为止:http://jsfiddle.net/DtbZ6/1/
您甚至可以扩展其中任何一个示例,以使用三个单独的setTimeout
调用,这些调用不会被重复,直到之前的三个调用都已执行,这意味着三个调用的顺序不一样,但它们永远不会重叠。