0

I am not very experienced in Javascript/JQuery. So I recently found out that Javascript is single threaded.
So I am trying to understand what are the implications of this:

  1. When writing code
  2. What is considered as bad practice to be done in Javascript as a result of this single threaded model

To give an example of what I am asking, in my mind when I found out about this, I immediately though of Java's Swing. In Java's case, the implication is that the code that is time consuming should be outside of the code that updates the UI.
Also concerning 2, I assume that an example of bad practice as a result of the single threaded nature is the recommendation to use server side push technologies instead of Ajax for real time updates. I assume this is the reason that it is preferred.

So can anyone explain the subtleties on this topic?

Jim
  • 18,826
  • 34
  • 135
  • 254
  • Why downvote?Can I improve this somehow? – Jim Feb 26 '14 at 21:27
  • 1
    [Not my DV] I 'm not sure what kind of answer you are expecting here. Since JS is single threaded and makes heavy use of async callbacks, the implication is that you should never write code that keeps monopolizing the thread for an amount of time that would be noticeable to a human (otherwise the UI will seem to hang). In effect it's cooperative task-switching, so you should cooperate. – Jon Feb 26 '14 at 21:28
  • JavaScript is a programming language, Swing is a library. A programming language is not parallel, the code that can be written using said language could be multi-threaded (parallel). This question does not make much sense to me... – Stefano Sanfilippo Feb 26 '14 at 21:29
  • @Jon:I can write code in Javascript to do what is needed but I don't really have a good understanding of what is the proper way to write good Javascript code. I read about the single threaded and I thought there are things that I could learn from this – Jim Feb 26 '14 at 21:29
  • 1
    @StefanoSanfilippo:Swing is a library for the UI and is designed to be single threaded.Javascript is a language for a UI (in web) and is designed to be single threaded – Jim Feb 26 '14 at 21:30
  • I think #2 is really more about minimizing network requests than it is about a single-threaded nature of Javascript. Ajax implies you need to poll the server constantly for updates whereas there are protocols available to not require this with server side push. – Rich Feb 26 '14 at 21:31
  • @Jim: One could say that the only way to really get a good picture of what good code is, is to write bad code and then recognize its shortcomings. – Jon Feb 26 '14 at 21:31
  • Just a small note, JavaScript is not only for the UI (think about Node.js). – g00glen00b Feb 26 '14 at 21:31
  • Another question answers the concept about 'single-threaded' in more detail http://stackoverflow.com/questions/2734025/is-javascript-guaranteed-to-be-single-threaded – Rich Feb 26 '14 at 21:33
  • @Jim I repeat, a programming language is not inherently single or multi threaded. The code you write using it is (or is not). Speaking of JS in web browsers, there is an ongoing implementation effort towards WebWorkers to enable multi-threading. – Stefano Sanfilippo Feb 26 '14 at 21:35
  • @StefanoSanfilippo Arguably, ECMAScript is *only* single-threaded - particularly because there is no provision for multiple threads in the specification. A version of ECMAScript with concurrent access across *shared* objects (as opposed a mechanism like Web Workers) would well, not be ECMAScript but an ECMAScript-based language that supported concurrent threads ;-) – user2864740 Feb 26 '14 at 21:36

1 Answers1

5

Swing (when not creating manual threads off the EDT) and browser JavaScript DOM/UI are very similar paradigms - the single-threaded/callback execution model transfers fairly well conceptually.

The same "implication" of one exists in the other - do not block the "UI thread" in any manner such that it impedes user interaction. (In my experience this is generally related to looping over or processing too large a data-set in a given event.)

SwingWorkers can be roughly thought of as Web Workers in that both provide an asynchronous abstraction over a concurrent execution context, where neither supports direct access to the UI. However, JavaScript has no way of "accidentally" touching shared data from different threads.

The use of AJAX/XHR or WebSockets in a "pull" vs a "push" approach is not directly related to the JavaScript concurrency model. They are merely separate means to the same end, and both are (nearly ubiquitously) handled asynchronously.


Usually, when needing to split up a long-running UI operation such as adding thousands of complex DOM elements (uhg!), I will use setTimeout in conjunction with an array acting as a queue. A trivialized non-generic example might look like the following:

function processItemsInUI (items) {
    var endTime = (+new Date) + 40 * 1000; // stop ~40ms in future
    var item;
    while ((items = items.shift()) && (+new Date) < endTime) {
       // have item, and limit not exceeded
       // processItem(item);
    }
    if (items.length) {
        // wait ~30s ms before doing more work
        setTimeout(function () { processItemsInUI(items) }, 30 * 1000);
    } else {
        // done!
    }
}

processItemsInUI(getManyManyItems());

Alternatives to the above include

  1. Reducing the amount of items fetched/displayed through filters, which simply avoids issues related to an excessive amount of UI work, and;

  2. Virtualizing item rendering, such as done in Slick Grid (or say a Tumblr archive view), to avoid creating DOM elements until they are actually "in view".

user2864740
  • 60,010
  • 15
  • 145
  • 220
  • But what is an example of a code in JS or JQuery that should be avoided as it blocks the UI? – Jim Feb 26 '14 at 21:43
  • @Jim *Any* operation that blocks the UI thread in such a manner that it impedes user interaction. – user2864740 Feb 26 '14 at 21:44
  • @Jim A "long operation" is *any* long operation - a trivial example is a loop that busy-waits for X seconds. – user2864740 Feb 26 '14 at 21:45
  • 1
    For example, generating a large graph of data using Canvas. If you had to draw a thousand-entry bar graph, you'd want to do it in chunks using setTimeout() or setInterval() to keep from impeding user interaction with your page. – user1329482 Feb 26 '14 at 21:45
  • So when you make an AJAX request to the server to retrieval a large amount of data but you use while loops until the request is complete, rather than a callback. – SomeShinyObject Feb 26 '14 at 21:48
  • Ok, sorry, what would be a method for a `for` callback, ([promise()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)?), and how would that be non blocking? – loveNoHate Feb 26 '14 at 22:00
  • @dollarVar Code execution takes time, of course. The issue is only when the time taken (before control is "yielded" back to the UI) impedes user interaction. For processing/looping over many items, one approach I have had success with is using setTimeout with an array that acts like a queue and then limiting the duration of the loop - it is often impractical to asynchronously queue each individual action, as the time for a single action is usually "trivial". Promises don't change the implications, but rather provide an alternative method of consuming and chaining callbacks in a unified model. – user2864740 Feb 26 '14 at 22:05
  • @dollarVar That is, a promise (like a callback) can be *used with* an asynchronous event source (such as setTimeout or XHR), but don't otherwise "add" any form of concurrency. – user2864740 Feb 26 '14 at 22:08
  • I do not want to capture this "thread" haha, but I am right now struggling with a `for` loop that kinda renders the view; until it is done, the window is not even scrollable. Could you put a JSFIDDLE of that non-blocking thing up, please? – loveNoHate Feb 26 '14 at 22:15
  • @dollarVar I've added a small example. Similar examples can be found in other SO questions. – user2864740 Feb 26 '14 at 22:30
  • Cool, the `Date` thing is hot. Never thought about that (and you did not put it up in the comments till now(Y)). So what would be the term to search for? I took "non-blocking" from NODE.js. – loveNoHate Feb 26 '14 at 22:35
  • 1
    @dollarVar "non-blocking" sounds like a good term. – user2864740 Feb 26 '14 at 22:42