2016-04-22 7 views
1

Bitte helfen! Ich mache ein Alarmsystem, das mehrere Warnungen zur gleichen Zeit auslöst, aber ich möchte, dass sie nacheinander erscheinen, so dass es wie ein Befehl aussieht. In bash ist es die Schlaffunktion.jquery .each Schleife, um jedes Array Element mit einer Verzögerung zwischen ihnen auszuführen

Werfen Sie einen Blick https://jsfiddle.net/14cmgrLj/10/

function iterateThru (message, status) { 
 
    var time = 500; 
 
    $.each(alertsArray, function(index, item) { 
 
    \t \t 
 
     \t //setTimeout(function(){ fireAlerts(message, status); }, 1000); 
 
     setTimeout(fireAlerts, 100, message, status); 
 
\t \t \t \t 
 
     //remove 
 
\t \t \t \t setTimeout(removeAlert, 4000); 
 
    }); 
 
    // empty array 
 
    alertsArray = []; 
 
    }

ich diese Funktion aus aller meiner Seite nenne. In dem Bemühen, sie 1-mal-1 auszulösen - jedes Mal, wenn meine Funktion verwendet wird, wird das Objekt zu einem Array hinzugefügt, und dann benutze ich .each, um jedes mit einem setTimeout zu durchlaufen, aber sie feuern alle gleichzeitig. Wie kann ich die Elemente des Arrays mit einer Verzögerung zwischen ihnen durchlaufen.

Vielen Dank im Voraus

+0

Sie Ihre Firealert und removeAlert Funktionen wie> – ayushgp

+0

Die setTimeouts Code asynchron auszuführen verursachen erwartungs das ist, was das verursacht wird Problem. Sie müssen stattdessen eine rekursive Schleife verwenden. – nurdyguy

+0

FireAlert und removeAlert Funktionen funktionieren, aber nicht so, wie ich es möchte. https://jsfiddle.net/14cmgrLj/10/ @ayushgp – Omar

Antwort

2

Sie jQuery verwenden könnte .delay Funktion der Warteschlange zu verwalten jQuery: Can I call delay() between addClass() and such?


Oder ...

eine IIFE to manage the incremental wait für jede Nachricht in der Schleife verwenden.

Fiddle: https://jsfiddle.net/14cmgrLj/11/

Es braucht ein wenig mehr Arbeit, weil, wenn Sie auf die Schaltfläche Alarm erstellen, nachdem der erste Satz beendet, aber bevor sie versteckt sind das Timing ist alles verrückt.

function fireAlerts(alerts) {  
    $.each(alerts, function(index, value) { 
    // Use IIFE to multiply Wait x Index 
    (function(index, value) { 
     var wait = index * 1000 + 1000; 
     setTimeout(function() { 
     // Show Alert 
     // [...] 
     } 
     }, wait); 
    })(index, value); 
    }); 
} 
+0

Sie sind ein Genie! Ich bin neidisch auf dein Wissen! Vielen Dank https://jsfiddle.net/14cmgrLj/12/ – Omar

+0

irgendwelche Ideen, wie ich einen Parameter verwenden könnte, um die Reihenfolge oder Wichtigkeitsgrad zu entscheiden? @Justin – Omar

+0

Sie können die Flex-Box Reihenfolge Eigenschaft verwenden, um die Reihenfolge, die ich glaube: http://StackOverflow.com/a/28159766/922522 – Justin

0

Wie bereits erwähnt, bevor SetTimeout planen nur Aufgaben und sofort zurückkehrt. So etwas wie folgt verwenden:

<script> 
var alertArray=[]; 
function showAlert(){ 
    var al = alertArray.shift();// removes and return first element 
    if(al !== undefined){ 
     alert(al); 
    } 
    setTimeout(showAlert, 4000); 
} 
setTimeout(showAlert, 4000); 
function addAlert(al){ 
    alertArray.push(al);//add new alert to the end 
} 
</script> 
0

Ok Also ich habe das Problem in Ihrem Code gefunden. Die Funktion setTimeout ruft den Code auf, der innerhalb der Funktion nach der angegebenen Zeit geschrieben wurde. Aber ist asynchron, dh es blockiert nicht. Also, wenn Sie über jedes Element Looping waren, wurden die Funktionen aufgerufen, alle drei ungefähr zur gleichen Zeit (Sie gab ihnen die gleiche Zeitüberschreitung). Was Sie tun müssen, ist eine neue Variable zu definieren (Zeit, in der jede Zeile erscheint) und diese in jeder Iteration zu erhöhen.

function iterateThru (message, status) { 
    var time = 0; 
    $.each(alertsArray, function(index, item) { 

     setTimeout(function(){ 
      fireAlerts(message, status); 
     }, time); 
     time += 1000; 

     //remove 
     setTimeout(removeAlert, 4000); //Change value of 4000 accordingly. 
    }); 
    // empty array 
    alertsArray = []; 
    } 
0

Die Art und Weise Sie die Dinge geschrieben hatte, war etwas seltsam Sachen zu tun, also ging ich mit dieser Änderung Ihrer Lösung:

  • Warnungen Fügen Sie den Bildschirm mit einem ‚warten‘ -Funktion von jQuery erstellt Deferred
  • Hinzufügen von Warnungen zu einem Array, wenn Sie sie brauchen (entkommentieren Sie das)
  • Ich habe Ihre Globals in einen Namespace namens myApp verschoben.

Probieren Sie es hier aus: https://jsfiddle.net/MarkSchultheiss/14cmgrLj/14/

Altered Code:

//create app or use one if exists 
var myApp = myApp || {}; 
// add alerts data 
myApp.alerts = { 
    count: 0, 
    alertDelay: 3000, 
    defaultStatus: "1", 
    alertsArray: [] 
}; 
myApp.func = { 
    wait: function(ms) { 
    var defer = $.Deferred(); 
    setTimeout(function() { 
     defer.resolve(); 
    }, ms); 
    return defer; 
    }, 
    addAlert: function(message, status) { 
    status = status || myApp.alerts.defaultStatus; 
    myApp.alerts.count++; // counts how many have ran 
    var alert = [message, status, myApp.alerts.count]; 
    // uncomment if you need keep track of them: 
    // myApp.alerts.alertsArray.push(alert); 
    myApp.func.fireAlert(alert, myApp.alerts.alertDelay); 
    }, 
    fireAlert: function(item, delay, index) { 
    $("#terminal").append("<span class='d" + item[2] + "'>" + item[0] + "</span><br />"); 
    myApp.func.wait(delay).then(function() { 
     $("#terminal").find('.d' + item[2]).addClass('fadeOutDown'); 
    }) 
    } 
}; 
//====== Trigger ======// 
$("#trigger").click(function(event) { 
    console.log("There have been " + myApp.alerts.count + " alerts ran"); 
    console.log(myApp.alerts.alertsArray); 
    myApp.func.addAlert($('#field').val(), 2); 
    myApp.func.addAlert($('#field').val(), 2); 
    myApp.func.addAlert($('#field').val(), 2); 
});