Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone events firing order

Say I have this:

view1.listenTo(model, 'change', function(){
    console.log('test1');
});

view2.listenTo(model, 'change', function(){
    console.log('test2');
});

Is it guaranteed that 'test1' will always print first?

like image 518
Vic Avatar asked Oct 01 '13 14:10

Vic


3 Answers

I don't know any case that the listeners work in a different way. I have read the backboneJs code to be sure, and I have seen that listenTo push the callback in an array. When the event is triggered, it loops an array that contains the event callbacks.

var triggerEvents = function (events, args) {
    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
    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, a1); return;
        case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
        case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
        default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
    }
};

I think you can be sure it won't change. Always the events work in that way. When the event happens (this.model.trigger("change") or this.model.set("...)) the callbacks are launched in order that they were definned and when the callbacks are launched the execution continues in the next line of the model modification.

like image 184
ccsakuweb Avatar answered Nov 09 '22 05:11

ccsakuweb


As @Daniel pointed out that documentation doesn't state anything particular about event ordering.

Based on my personal experience I have never seen events firing in random order.

This working DEMO confirms it.

Demo code:

   var Person = Backbone.Model.extend({ 
     initialize: function(){
            console.log("Welcome to this world");
        }
   });

  var person = new Person({ name: "Thomas", age: 67, child: 'Ryan'});

   var headerView = Backbone.View.extend({    

        initialize: function() {

             this.listenTo(person, 'change', function(){
                console.log('test1');
             });      

            this.listenTo(person, 'change', function(){
                console.log('test2');
             });      

             this.listenTo(person, 'change', function(){
                console.log('test3');
             });      

            this.listenTo(person, 'change', function(){
                console.log('test4');
             });      

             this.listenTo(person, 'change', function(){
                console.log('test6');
             });      

            this.listenTo(person, 'change', function(){
                console.log('test7');
             });      

        }        
     });

   new headerView();

setInterval(function(){
    person.unset('attr');
    person.set({'attr': 'value'});
},1000)
like image 4
Gurpreet Singh Avatar answered Nov 09 '22 05:11

Gurpreet Singh


In its current implementation, i would say yes. The documentation does not state that, however and that can change at anytime.

like image 2
Daniel A. White Avatar answered Nov 09 '22 03:11

Daniel A. White