2009-07-02 100 views
1

我正在構建一個演唱會日曆,它對JavaScript非常沉重(使用jQuery)。我在整個應用中同步各種事件時遇到問題,並且正在尋找如何執行此操作的建議。Javascript事件同步

一個簡單的採用情況的示例:

  1. 用戶點擊一個月
  2. 日曆跳到那個月

一個更復雜的使用情況的一個例子:

  1. 用戶選擇一位藝術家
  2. 日曆確定t他那藝術家的首秀日期
  3. 日曆跳到那個月
  4. 日曆強調了藝術家的表演(S)

一個偶然的問題是,新的月還沒有通過我嘗試的時間呈現突出顯示藝術家的節目。因此,即使按順序調用這些功能,也不會突出顯示。顯然,使用setTimeout()非常不方便,並且不能保證能夠正常工作。

所以,首先,一個簡單的問題 - 即使在Chrome中也可能會出現以下功能失效:

function steps(){ 

    stepOne(); //TAKES 30 SECONDS 

    stepTwo(); //TAKES < 1 SECOND 

} 

其次,相關的簡單問題:

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

如果是這樣,我窩都充當了前一功能的回調。但是,一旦考慮到所有不同的用例,這可能會變得很難處理。

這裏是我考慮的方法:

 
    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. 

我想這將保證所有的函數調用秩序。

另一種方法是使用

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

,然後調用

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

每當事件發生時附加事件偵聽器。

但是,我猜這樣做會很笨拙,因爲考慮到不同的事件可能需要根據用例調用不同的函數集。我可以隨時撥打

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

添加新的事件之前,但再次 - 我朝着建立一個排序主「腳本」,因爲我在第一種方法建議傾斜。

希望這不是太模糊 - 任何反饋?任何需要同步各種事件的複雜UI的經驗?

非常感謝,

邁克爾

回答

1

你的方法#1是最好的方式,也是最自然的使用jQuery。大多數作用於用戶界面並執行某些操作的函數接受一個回調函數參數,該參數在函數執行後被調用。

如果你正在做的事情沒有在jQuery中實現,遵循相同的模式將使你的代碼更具可讀性。 Dominic的答案是一個很好的簡潔例如:

function steps(){ 

    stepOne(stepTwo); 

} 

function stepOne(callback){ 

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

} 
+0

我覺得這是它遵循的jQuery約定好點。不過,我發現有些時候,設置1ms的超時時間可以使事情發生在以前沒有的地方。這對我來說沒有任何意義(如果JS調用真的按順序執行 - 當然不包括異步調用),但是現在我必須忍受這種黑客攻擊。謝謝大家 - 所有的建議非常感謝:) – marclar 2009-07-08 01:37:37

1

嘗試傳遞函數被調用回作爲參數

function steps(){ 

    stepOne(stepTwo); 

} 

function stepOne(callback){ 

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

} 
1

最後一種方法,使用自定義的事件,是在我的愚見最好的辦法。

設計各種組件和事件,讓它們相互交互。

E.g.假設你有一個Calendar對象。現在

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

您的音樂搜索方法可能看起來像,

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

    calendar.selectMonth(getShowMonthByArtist(artistName)); 
}