2009-07-02 12 views
1

Ich baue einen Konzertkalender, der sehr schwer auf Javascript (mit jQuery) ist. Ich habe Probleme, verschiedene Ereignisse in der App zu synchronisieren, und ich suche nach Vorschlägen, wie das geht.Javascript Event Synchronisation

Ein Beispiel für einen einfachen Anwendungsfall:

  1. Benutzer einen Monat in diesem Monat
  2. Kalender überspringt klickt

Ein Beispiel für einen komplexeren Anwendungsfall:

  1. Benutzer wählt einen Künstler aus
  2. Kalender bestimmt t er Datum dieser ersten Ausstellung des Künstlers
  3. Kalender überspringt in diesem Monat
  4. Kalender macht deutlich, dass Künstler Show (s)

Ein mögliches Problem ist, dass der neue Monat ist noch nicht von der Zeit gemacht ich versuche, um die Show (n) des Künstlers hervorzuheben. Daher wird die Show nicht hervorgehoben, obwohl diese Funktionen der Reihe nach aufgerufen werden. Offensichtlich ist setTimeout() ziemlich hacky und funktioniert nicht garantiert.

Also zuerst, eine einfache Frage - wäre es jemals möglich (auch in Chrome) für die folgende Funktion aus der Reihe zu laufen?

function steps(){ 

    stepOne(); //TAKES 30 SECONDS 

    stepTwo(); //TAKES < 1 SECOND 

} 

Zweitens, eine verwandte einfache Frage:

 
    If placed at the end of a function, will a JS callback ALWAYS run after 
    everything else in the given function has finished running? 

Wenn ja, ich konnte Nest jede Funktion als Rückruf seiner vorherigen Funktion. Aber das würde wahrscheinlich unhandlich werden, wenn man die verschiedenen Anwendungsfälle betrachtet.

Hier ist ein Ansatz, den ich überlege mir:

 
    1) Allow each function an optional callback parameter. If it's present, 
     call it at the very end of the function. 

    2) During a UI refresh, create an array, and stack any functions to be 
     called within this array. 

    3) Once this "script" is completed, iterate through the array, calling 
     each function in the order it was added, using the next function 
     as the previous function's callback. 

Ich stelle mir dies würde sicherstellen, dass alle Funktionen in Reihenfolge aufgerufen werden.

Ein weiterer Ansatz ist Ereignis-Listener mit

$(document).bind("listener.name", fnCallback); 

Und dann ruft

$(document).trigger("listener.name"); 

Jedes Mal, wenn das Ereignis eintritt zu befestigen.

Ich denke jedoch, dass dies auch etwas unhandlich wäre, wenn man bedenkt, dass verschiedene Ereignisse abhängig vom Anwendungsfall unterschiedliche Funktionen aufrufen müssen. Ich konnte immer

$(document).unbind("listener.name"); 

vor dem Hinzufügen neuer Ereignisse nennen, aber auch hier - ich bin Neigung Art eines Master „Drehbuch“ zu erstellen, wie ich im ersten Ansatz vorgeschlagen.

Hoffentlich ist das nicht zu vage - keine Rückmeldung? Irgendwelche Erfahrungen mit komplexen UIs, die verschiedene Ereignisse synchronisieren mussten?

Vielen Dank,

Michael

Antwort

1

Ihr Ansatz # 1 ist die beste Art und Weise, und die natürlichste jQuery verwenden. Die meisten Funktionen, die auf der Benutzerschnittstelle wirken und etwas tun, akzeptieren einen Callback-Funktionsparameter, der nach Ausführung der Funktion aufgerufen wird.

Wo Sie Dinge tun, die nicht in jQuery implementiert sind und demselben Muster folgen, macht Ihren Code lesbarer. Dominics Antwort ist ein gutes Beispiel lapidar:

function steps(){ 

    stepOne(stepTwo); 

} 

function stepOne(callback){ 

    var AsyncDone = function() { 
     //any Synchronus Things here 
     callback(); 
    } 
    someAsyncFunction(params, AsyncDone); 

} 
+0

Ich denke, das ein guter Punkt ist, dass es jQuery Konvention folgt. Ich habe jedoch festgestellt, dass es manchmal Situationen gibt, in denen ein Timeout von 1 ms funktioniert, wo es vorher nicht war. Das macht für mich keinen Sinn (wenn JS-Aufrufe wirklich in der richtigen Reihenfolge ausgeführt werden - natürlich ohne asynchrone Aufrufe), aber es ist ein Hack, mit dem ich jetzt leben muss. Danke, jeder - alle Ratschläge sehr geschätzt :) – marclar

+1

Ich dachte, dass Code bekannt vorkam! :) – DMCS

1

Versuchen in der Funktion übergibt als Argument aufgerufen werden, zurück zu

function steps(){ 

    stepOne(stepTwo); 

} 

function stepOne(callback){ 

    var AsyncDone = function() { 
     //any Synchronus Things here 
     callback(); 
    } 
    someAsyncFunction(params, AsyncDone); 

} 
1

Der letzte Ansatz, von benutzerdefinierten Ereignissen verwendet wird, ist der beste Ansatz in meiner bescheidenen Meinung nach.

Entwerfen Sie verschiedene Komponenten und Ereignisse, und lassen Sie sie miteinander interagieren.

z. Nehmen wir an, Sie haben ein Kalenderobjekt.

var calendar = function() 
{ 
    var pub = {}; 


    pub.highlightRow = function(row) {}; 

    pub.getRowByContent = function(content) { }; 

    pub.selectMonth = function() 
         { 
          //your code to actually select month. 

          //Once all the necessary DOM work is done, fire the 
          //monthSelected event (namespacing the event so as to avoid the clash with other events). 
          $(document).trigger('calendar:monthSelected'); 
         }; 

    return pub; 
}(); 

Jetzt ist Ihre Künstler Suchmethode aussehen kann,

function searchArtist(artistName) 
{ 
    $(document).bind('calendar:monthSelected'), function() 
               { 
                calendar.highlightRow(calendar.getRowByContent(artistName)); 
               } 
               ); 

    calendar.selectMonth(getShowMonthByArtist(artistName)); 
}