brushleaf
brushleaf

Reputation: 1215

Are browser events in JavaScript asynchronous?

In John Resig's book "Secrets of the Javascript Ninja", he makes the following assertion:

Programming for the browser is no different, except that our code isn’t responsible for running the event loop and dispatching events; the browser handles that for us.

Our responsibility is to set up the handlers for the various events that can occur in the browser. These events are placed in an event queue (a FIFO list; more on that later) as they occur, and the browser dispatches these events by invoking any handlers that have been established for them.

Because these events happen at unpredictable times and in an unpredictable order, we say that the handling of the events, and therefore the invocation of their handling functions, is asynchronous.

I am having a hard time accepting the use of the term asynchronous here. Doesn't he really mean achronological? They may also be asynchronous, but not for the reasons presented to support this statement. Thoughts?

Upvotes: 16

Views: 10488

Answers (7)

Neil Laslett
Neil Laslett

Reputation: 2149

Just stumbled on this very old thread with very modern implications. Despite the common wisdom that "JavaScript is single-threaded", event firing is indeed asynchronous.

Test this out in any browser running jQuery:

$('body').click(function () { setTimeout(f => alert('foo'), 1000); });
function calltrigger() { $('body').click(); alert('bar'); }
calltrigger();

This does three things and proves the point:

  1. Adds an onClick event to the body, with alert('foo') with a 1 second delay.
  2. Defines an anonymous function that first triggers that onClick event, then calls alert('bar').
  3. Calls the anonymous function.

If the onClick event in the function were blocking (synchronous), you would see the "foo" alert before the "bar" alert. But you do not. The onClick event is triggered asynchronously and the alert('bar') fires first, followed by the alert('foo').

Instead, the onClick event fires and the code moves on to the second alert before the event code completes.

Upvotes: 0

user471769
user471769

Reputation:

Your question title and your question body seem to be asking two different things. I'll try to address both.

The Body Question

asynchronous is not a term that John coined or even a JavaScript specific term. It has a established meaning in computer science. And although what John says is accurate, I think it's incomplete. He is correctly explaining why we use the term asynchronous (the etymology), but not explains what asynchronous programming is.

In computer science, asynchronous means suspending executing code, allowing other (arbitrary) code to run in the same thread, and eventually resuming the suspended code. There are many techniques for accomplishing this and many ways of abstracting this for the programmer, but they all share the trait of suspending code rather than blocking. This is utilized to avoid blocking an entire thread while waiting for some slow resource (like an HTTP request, a file, or a database).

For example, if you were to make a synchronous HTTP request, then no other JavaScript could run until the request completes. So any part of the web page that depends on JavaScript would be frozen. However, if you make an asynchronous HTTP request, the code making the request can be suspended while it waits on the request. This allows other code to execute. And after the HTTP request is complete, the request code can resume.

The reason John says asynchronous code can happen is any order is because we don't know when external resources will be available. For example, if you make two or more asynchronous HTTP requests, there is no way to know in what order the requests will complete (consequently, what order the code will be resumed).

The Title Question

Browser events are asynchronous in the same way our example HTTP request is. In fact, in many ways the user as just an other external resource. The user will do things on their own time, asynchronous of what code is currently executing.

For example, if your code defines a handler for the click event of a button on the page. Your JavaScript code doesn't wait on the user to click the button. It suspends that code for the click handler and executes it later when the user clicks the button. This gets to the heart of why asynchronous programming is so important in JavaScript. If your code simply blocked (waited) until that HTTP request was complete, the user could not click the button. And if your code blocked while waiting on the user to click something, then your HTTP request would timeout.

Final Thoughts

In JavaScript, we don't often think suspending and resuming code. In fact you can't just suspend in the middle of an running block of code. The block will always complete before anything else is executed. Instead we pass callbacks out of our code block to be executed later. These callbacks can take along with them access to resources (scope) from the original code block. The callback is what is resumed from the original context.

This is a good resource if you want to dive deeper in to how JavaScript manages Concurrency model and Event Loop. Also, JavaScript has added some powerful abstractions to the event loop beyond callback, such as Promises and Generators. These are worth spending some time on.

Upvotes: 8

Ruan Mendes
Ruan Mendes

Reputation: 92274

The way it's worded, I think it's technically correct (and you may disagree) albeit confusing. I would have worded it differently since it seems to indicate that your JavaScript execution call be preempted.

the invocation of their handling functions, is asynchronous.

The invocations of handlers (done by the browser itself, probably in C or C++, not JavaScript) does happen asynchronously, that is, there are other threads that add events to the queue, meaning that the event loop is preempted.

He did not say that the handlers execution is asynchronous. Those are guaranteed to run to completion and not be preempted (by other JavaScript).

I think another thing that is bothering you is

Because these events happen at unpredictable times and in an unpredictable order,

This is not saying that no events run in a predictable order but some do, so it's technically also correct but misleading as you showed with your setTimeout example. For example:

  • XHR requests
  • Multiple handlers on the same node used to not have guaranteed order back then, but they do now

Also note that if you do fire a synthetic event, or call click() on an element, all its handlers will be called immediately (jumping the queue), a new event does not go into the queue.

Upvotes: 1

user166390
user166390

Reputation:

Because these events happen at unpredictable times and in an unpredictable order, we say that the handling of the events, and therefore the invocation of their handling functions, is asynchronous.

This is a white-lie; a bit of a hyperbole to make a point, perhaps. However;

  • Events without a well-defined order can happen in an unpredictable order.

    Example: AJAX requests - which response arrives first?

  • Events with a well-defined order occur in a predictable order.

    Example: setTimeout(a); setTimeout(b); - a will be invoked prior to b.

Take it with a grain of salt, and don't make too much of it.

Upvotes: 3

bfavaretto
bfavaretto

Reputation: 71918

I believe what Resig means is, UI events must be handled asynchronously by browsers, otherwise the UI would block if e.g. a click was performed while something else was being processed. Usually, desktop software solves that problem with multithreading. Web apps rely on JavaScript, which uses an event loop to achieve asynchrony.

Upvotes: 0

Explosion Pills
Explosion Pills

Reputation: 191749

Event handling is identical for ajax requests as it is for user initiated events. When you call xhmlhttprequest.open, you initiate an asynchronous call that is handled by the onreadystatechange event upon request completion (which could come at any time). Similarly, the user could initiate an event on a DOM element at any time.

The handling of events and the invocation of their callbacks is asynchronous, but not necessarily the callbacks themselves.

I found this as a definition too:

Of or requiring a form of computer control timing protocol in which a specific operation begins upon receipt of an indication (signal)

That signal could be a click event or an xmlhttprequest ready state change.

Upvotes: 2

MaxOvrdrv
MaxOvrdrv

Reputation: 1916

JavaScript IS asynchronous... it will continue to process code, even if a method you called hasn't returned yet... so yes, that is correct. That is the very definition of async: NOT synchronized...

i get your query though... because of FIFO... but i think the term used is appropriate... since it's defined exactly as they state it.

Upvotes: -1

Related Questions