Are methods associated with events called asynchronously or not in Javascript / Backbone.js?

I am wondering if the methods associated with the events are called asynchronously or not in javascript? In my case, I use Backbone.js to create the application. I use an event aggregator to communicate between views.

If I have a method that fires an event, will methods be fired in other views associated with this event before the rest of the method that raises the trigger event is fired?

The event aggregator is as follows:

var eventAggrigator = _.extend({}, Backbone.Events); eventAggrigator.on('submitContactEditForm', function() { console.log('Contact edit form submit event triggered'); }); 

Function call that raises the event (this function is called from ViewA):

 saveContact: function(event) { var self = this; // Prevent submit event trigger from firing. event.preventDefault(); // Trigger form submit event. eventAggrigator.trigger('submitContactEditForm'); // Update model with form values. this.updateContact(); // Save contact to database. this.model.save({ success: function(model, response) { console.log('Contact ' + self.model.get('surname') + ' saved'); }, error: function(model, response) { throw error = new Error('Error occured while saving contact.'); } }); }, 

The ViewB is attached to the event 'submitContactEditForm' (see the corresponding code from the ViewB below):

 initialize: function() { _.bindAll(this, 'addSortableFields', 'appendNewField', 'getFieldsHtml', 'removeField', 'render', 'setEmailValues'); // Bind to event aggregator. eventAggrigator.bind('submitContactEditForm', this.setEmailValues); this.model = this.options.model; }, setEmailValues: function() { // Extract email form values. var emails = _.clone(this.model.get('email')); var emailFields = this.$('.email-field'); _.each(emails, function(email, index) { email.value = emailFields.eq(index).val(); }); this.model.set('email', emails); }, 

So the question will be, will ViewB.setEmailValues ​​() always execute before this.model.save () in ViewA.saveContact () is executed?

+4
source share
2 answers

The relevant part, where events are triggered in the trunk, is as follows:

 trigger: function(events) { var event, node, calls, tail, args, all, rest; if (!(calls = this._callbacks)) return this; all = calls.all; events = events.split(eventSplitter); rest = slice.call(arguments, 1); // For each event, walk through the linked list of callbacks twice, // first to trigger the event, then to trigger any `"all"` callbacks. while (event = events.shift()) { if (node = calls[event]) { tail = node.tail; while ((node = node.next) !== tail) { node.callback.apply(node.context || this, rest); } } if (node = all) { tail = node.tail; args = [event].concat(rest); while ((node = node.next) !== tail) { node.callback.apply(node.context || this, args); } } } return this; } 

As you can see, event handlers are called synchronously one after another.

Warning. If your handlers make asynchronous calls, then of course they will not be completed until the completion of the run loop after trigger . This can be mitigated by using callbacks, which can lead to completion or better using the "Deferred" / Promises parameter.

+4
source

This is a very interesting question with a very interesting answer.

I expected this behavior to be asynchronous, but turned out to be synchronous .

I based my conclusion on this code:

 var MyModel = Backbone.Model.extend(); var oneModel = new MyModel(); oneModel.on( "event", eventHandler1 ); oneModel.on( "event", eventHandler2 ); function eventHandler1(){ for( var i = 0; i < 10; i++ ){ console.log( "eventHandler1", i ); } } function eventHandler2(){ for( var i = 0; i < 10; i++ ){ console.log( "eventHandler2", i ); } } function testEvent(){ console.log( "testEvent::INI" ); oneModel.trigger( "event" ); console.log( "testEvent::END" ); } testEvent();​ 

This leads to this conclusion:

 testEvent::INI eventHandler1 0 eventHandler1 1 eventHandler1 2 eventHandler1 3 eventHandler1 4 eventHandler1 5 eventHandler1 6 eventHandler1 7 eventHandler1 8 eventHandler1 9 eventHandler2 0 eventHandler2 1 eventHandler2 2 eventHandler2 3 eventHandler2 4 eventHandler2 5 eventHandler2 6 eventHandler2 7 eventHandler2 8 eventHandler2 9 testEvent::END 

Check out jsFiddle .

0
source

Source: https://habr.com/ru/post/1416301/


All Articles