簡體   English   中英

順序運行多個setIntervals

[英]Sequentially running multiple setIntervals

我正在嘗試運行多個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是異步的,因此三個間隔並行運行並且正在弄亂間隔:

培根很棒啊

啤酒很棒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庫,但是我找不到合適的控制流程。

這對我練習一些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);
});

演示

我做了一個叫做`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));
        }
    });
};

演示: http//jsfiddle.net/howderek/L5nhU/

你可以使用例如 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 
... 

一旦你調用了setIntervalsetTimeout你就掌握在瀏覽器中; 通過的時間並不保證是准確的,並且不能保證執行多個回調的順序 - 通常不會。

如果要強制執行順序,使用setTimeout而不是setInterval將使您有機會決定每次回調完成時會發生什么。

這是一個小提琴首先迭代培根,然后是啤酒,然后是牛排: http//jsfiddle.net/q96Vc/

這是一個一個接着顯示每個標簽直到30秒為止的一個: http//jsfiddle.net/DtbZ6/1/

您甚至可以擴展這些示例中的任何一個以使用三個單獨的setTimeout調用,這些調用在前三個調用都已執行之前不會重復,這意味着三個調整的順序會有所不同,但它們永遠不會重疊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM