2009-07-02 78 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)); 
}