2012-12-18 14 views
10

Buduję ogólny widok kręgosłupa w celu zarządzania wieloma widokami podrzędnymi. Czasami muszę wykonać logikę, aby przygotować te widoki, zanim zostaną renderowane. Jestem rozważa wykorzystanie zdarzeń kręgosłup umożliwić hak pre_render, tak:Czy wyzwalacz kręgosłupa() jest synchroniczny czy asynchroniczny?

view = new (this.child_view); 
this.trigger('pre_render', view); 
view.render(); 

Czy zdarzenia wywoływane przez trigger() być wykonywane synchronicznie, co gwarantuje, że będą one zakończyć przed linią render() nazywa?

Odpowiedz

11

Zasadniczo tak, jest synchroniczny.

Oto odnośny odcinek od źródła:

trigger: function(name) { 
    if (!this._events) return this; 
    var args = slice.call(arguments, 1); 
    if (!eventsApi(this, 'trigger', name, args)) return this; 
    var events = this._events[name]; 
    var allEvents = this._events.all; 
    if (events) triggerEvents(this, events, args); 
    if (allEvents) triggerEvents(this, allEvents, arguments); 
    return this; 
}, 

Funkcja importu jest triggerEvents, które faktycznie wywołuje ładowarki. Według comments, jest to po prostu zoptymalizowany dyspozytor. Zauważ, że wszystkie wywołują .call() i .apply(), więc wywołanie zwrotne zostanie zakończone, zanim sterowanie zostanie przekazane z powrotem do osoby dzwoniącej.

var triggerEvents = function(obj, events, args) { 
    var ev, i = -1, l = events.length; 
    switch (args.length) { 
    case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); 
    return; 
    case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0]); 
    return; 
    case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1]); 
    return; 
    case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]); 
    return; 
    default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); 
    } 
}; 

Jak już wspomnieli inni, operatory obsługujące wyzwalacze mogą dowolnie planować własne wywołania zwrotne, jeśli są tak skłonne. Zatem to, czy osoby odpowiedzialne za obsługę zakończą swoją pracę przed powrotem, zależy od samego kodu obsługi.

2

Tak, są synchroniczne. Jednak funkcja wyzwalana przez to zdarzenie jest wolna w użyciu setTimeout lub wywoływać żądania ajaxowe, a jeśli tak, to nie zostaną one zakończone do czasu powrotu połączenia trigger, a kod przechodzi do wywołania render. Tak więc każda związana obsługa zdarzenia będzie wywoływana, ale niekoniecznie zakończyła cały proces przetwarzania. Ponieważ sam interfejs wyzwalacza nie obsługuje wywołań zwrotnych ani obietnic, nie ma prostego sposobu na określenie, kiedy wszystkie programy do obsługi zdarzeń są kompletne. Jeśli to konieczne, musisz sam wdrożyć taki interfejs API i wystrzelić odrębne zdarzenie, gdy wszystko zostanie zakończone, w tym przetwarzanie asynchroniczne. Jednak w programowaniu codziennym większość tych programów obsługi zdarzeń jest synchroniczna, a jeśli nie, kod jest zwykle zorganizowany w taki sposób, że postępowanie nie spowoduje niewłaściwego działania aplikacji. Jeśli chcesz zmienić tę umowę, jest to zapach kodu, którego projekt aplikacji nie harmonijnie korzysta z systemu zdarzeń i możesz pomyśleć o różnych podejściach do problemu.

1

wyzwalacz jest synchroniczny zgodnie z kodem źródłowym, nie oznacza, że ​​wszystkie funkcje, które nasłuchują zdarzenia "pre_render" wykonają synchroniczne operacje przez . PS: kod źródłowy jest bardzo łatwe do odczytania, naprawdę powinieneś rzucić okiem na to:

http://backbonejs.org/docs/backbone.html

+1

pewno znaleźć uwagami źródło użytecznych; Najczęściej lubię zostawiać papierowy ślad, odpowiadając na takie pytania. Dzięki! –

Powiązane problemy