18

The trigger function appears to be synchronous. That is, all bound functions appear to be executed in sequence, synchronously (the invoked function may do something asynchronously, but that's not the question).

Is this true for custom and non-custom(click, hover, etc) events? Are there any events where the single threaded guarantee of Javascript does not hold true?

If it is true, can the behavior be changed to execute them asynchronously without inserting timeouts into each bound function?

Here is a sample which demonstrates The question:

var ele = $('#blah');
// Example of the bound function doing something synchronously
ele.bind('customEvent.sync', function() {
    // Do something synchronously
    window.foo = 'foo';
});

// Example of the bound function doing something asynchronously
ele.bind('customEvent.async', function() {
    window.setTimeout(function() {
        // Do something asynchronously
        window.bar = 'bar';
    }, 0);
});

// Trigger both events
ele.trigger('customEvent');

// If trigger is guaranteed to be synchronous this should alert 'foo:undefined' or possibly 'foo:bar' depending on whether the asych function was called first
// If trigger is NOT synchronous 'undefined:undefined', 'foo:undefined', 'undefined:bar', or 'foo:bar' could be alerted
alert(window.foo + ':' + window.bar);

UPDATE See: Is JavaScript guaranteed to be single-threaded? Custom events are guaranteed to be synchronous because of the single threaded nature of Javascript. Some built in event types may not be synchronous due to browser inconsistencies.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Kyle
  • 1,019
  • 1
  • 10
  • 19
  • be a lot easier to follow if you gave example of what your concerns are – charlietfl Dec 24 '12 at 04:22
  • My concern is whether I can rely on the bound functions called my trigger to be executed before the line following the call to trigger – Kyle Dec 24 '12 at 04:27
  • The question seems to be conflicting: "the invoked function may do something async .. but that's not the question" and "can the behavior be changes with execute async without inserting timeouts into each bound function" (I though that was *not* the question?) –  Dec 24 '12 at 04:29
  • Events have no duration; providing a handler is attached, they cause a thread to start. Therefore an event, in itself, can be neither synchronous nor asynchronous. The thread that an event stimulates (triggers) will always be synchronous but may kick off one or more asynchronous processes. – Beetroot-Beetroot Dec 24 '12 at 04:30
  • based on @Beetroot-Beetroot comment, sure..the actual trigger will be synchronous.. still not clear why the concern in the first place other than hypothetical question or you have an asynchronous function such as an animation or AJAX being called within an event that is triggered – charlietfl Dec 24 '12 at 04:36
  • @pst The invoked function may do something asynchronously regardless of whether it was invoked synchronously or not(like an ajax call). – Kyle Dec 24 '12 at 04:39
  • is that a statement or a question.. if event handler has ajax call in it, your other code will fire before ajax complete... you would need to use a deffered or ajax callback for next code if you needed that ajax completed first – charlietfl Dec 24 '12 at 04:41
  • @charietfl a statement, see my edited question. I understand that the bound function invoked by triggering an event may perform an asychronous action(like an ajax call). My question is whether the call to trigger is completely synchronous(disregarding the synchronous/asychronous behavior the bound function). – Kyle Dec 24 '12 at 04:43
  • OK..question is better put as order of execution of 2 handlers for same event being triggered – charlietfl Dec 24 '12 at 04:46
  • @charlietfl That's not the question. – Kyle Dec 24 '12 at 04:47
  • 2
    Yes, the call is synchronous regardless of any asynchronous processes that might be started in the triggered event handler. When the triggered handler returns, execution reverts to the statement following `.trigger(...)`. ie, `.trigger()` is a glorified function call. – Beetroot-Beetroot Dec 24 '12 at 04:50
  • no matter what order the 2 execute in..the asynch setTimeout won't update `window.bar` before the alert fires.. using `1 ms` is perhaps debatable if it would or not but chances are it won't – charlietfl Dec 24 '12 at 04:54
  • 1
    Current thread is absolutely guaranteed to run to completion before anything put in place with `setTimeout()`, even if the timeout duration is 0. Same with ajax - a thread that calls, say, `$.ajax(...)` is guaranteed to run to completion before any of the success/error/complete handlers commences, even of the server was to respond immediately. – Beetroot-Beetroot Dec 24 '12 at 05:03
  • @Beetroot-Beetroot Is that true on all modern browsers? Is it part of the javascript spec? – Kyle Dec 24 '12 at 05:04
  • perhaps you've run into an odd group of events like this example @Kyle http://jsfiddle.net/vaE6t/1/ – charlietfl Dec 24 '12 at 05:20
  • 1
    It's inherent to ECMA-262 (javascript), which is strictly single-threaded, ie. at any moment in time, a maximum of one thread can be running. – Beetroot-Beetroot Dec 24 '12 at 05:21
  • @Beetroot-Beetroot ECMAScript is strictly single-threaded - or rather, it *doesn't define (or restrict) the usage of threads* - so it is silly to talk about "threads" I think :( –  Dec 24 '12 at 05:26
  • @Beetroot-Beetroot Thanks. This question's answer makes me nervous: http://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded but seems to be limited to certain edge case event types in certain browers. Consolidate your comments into an answer and it handles my immediate concerns. Perhaps add the caveats referred to in the previously mentioned question. – Kyle Dec 24 '12 at 05:27

1 Answers1

19

A lightly modified anthology of comments offered above by myself - Beetroot-Beetroot :

  • Events have no duration; providing a handler is attached, they cause a thread to start. Therefore an event, in itself, can be neither synchronous nor asynchronous. The thread that an event stimulates will always be synchronous but may kick off one or more asynchronous processes.

  • A call to .trigger() is always synchronous regardless of any asynchronous processes that might be started in the triggered event handler. When the triggered handler returns, execution reverts to the statement following .trigger(...). ie, .trigger() is a glorified function call.

  • In javascript, the current thread is absolutely guaranteed to run to completion before anything put in place with setTimeout() starts, even if the timeout duration is 0. Same with ajax - a thread that calls, say, $.ajax(...) is guaranteed to run to completion before any of the success/error/complete handlers commences, even if the server was to respond immediately.

  • Single-threadedness is inherent to ECMA-262 (javascript), ie. at any moment in time, a maximum of one thread can be running.

Additional point :

The acceped answer to Is javascript guaranteed to be single-threaded? is based on a false premise. No evidence is offered that javascript is not single-threaded. The comment by @KrisGiesing debunks the misunderstanding.

Community
  • 1
  • 1
Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44