15

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?

Community
  • 1
  • 1
brushleaf
  • 1,205
  • 3
  • 18
  • 26
  • Maybe you should add your own understanding of what *asynchronous* means. If you're just asking if the book is wrong or not, I'm thinking the discussion is not constructive. – bfavaretto Mar 10 '13 at 02:31
  • 1
    Clearly I am not the only one having trouble with his "definition", so I'd say it's pretty constructive. – brushleaf Mar 24 '13 at 14:05
  • @brushleaf, it's not really relevant who does and who doesn't have a problem with it. The question is asking for opinions, thoughts, and judgement calls. Read the FAQ -- this is squarely a "not constructive" question. Also note that *someone* is arguing in the comments with nearly every answer -- a good sign of a subjective question. – Ben Lee Apr 02 '13 at 22:27
  • And for the record, "asynchronous" is *very* standard usage for this in the industry, not achronological -- my *opinion* and *judgement call* is that your analysis is incorrect. The technical meanings for the terms synchronous and asynchronous are not exactly the same as the common meanings. – Ben Lee Apr 02 '13 at 22:29

7 Answers7

6

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.

Ben
  • 3,255
  • 1
  • 26
  • 32
3

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.

  • 2
    I believe he's talking about UI events like clicks, keyboard input, etc. Those are surely unpredictable. But I like your last sentence! :) – bfavaretto Mar 10 '13 at 02:23
2

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.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • Agreed, another way to say it is that your event handlers are run synchronously, that is, once an event handler has been called, its stack must unwind before a new event in the queue is handled. It's also important to note that if you synthetically fire an event from an event handler, attached handlers will also be called synchronously (jumping the queue). – Ruan Mendes Nov 20 '19 at 13:26
1

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.

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
0

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.

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • Desktop apps also rely on event loops that operate on a single thread, which is managed by the OS. This answer doesn't convince me that Resig is using the term correctly. – brushleaf Mar 10 '13 at 02:01
  • I understand that my explanation is not very convincing. My point is, asynchrony is necessary to handle UI events (with event loops or multithreading, it doesn't matter), or something would have to block. To me, that's the real meaning of that paragraph. – bfavaretto Mar 10 '13 at 02:14
  • I think you're right, that is his meaning, I just think he is using the wrong terminology. – brushleaf Mar 24 '13 at 14:06
0

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.

Neil Laslett
  • 2,019
  • 22
  • 22
-1

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.

MaxOvrdrv
  • 1,780
  • 17
  • 32
  • 4
    JavaScript is single-threaded. Browsers implement threads to handle events and such, but JavaScript itself isn't asynchronous. – Blender Mar 10 '13 at 01:36
  • true... sorry meant to write: can be used async... but the definition/statement made in the quote, about the order of the events firing, is accurate/is async... – MaxOvrdrv Mar 10 '13 at 01:39
  • This is not true. JavsScript will not "process code, even if a method you called hasn't returned yet". Each message in the event loop runs to completion. Click here for mozilla's documentation on the the JavaScript [Concurrency model and Event Loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop). – Ben Apr 05 '16 at 19:19
  • JS code execution is synchronous, unless you call async methods and instruct them to execute [sync] code block after it async method completes – Sergey P. aka azure Jan 18 '17 at 10:17