7

I hear people talking about asynchronous operations in javascript. On the other hand, people say that Javascript is always synchronous sync javascript. Which is true? Is Javascript really asynchronous or synchronous? What do people mean when they talk about asynchronous javascript?

What I have understood is that Javascript on the same page cannot be run concurrently with another block of code of javascript. But for example in ajax requests, while waiting for the server response, one could execute code, and then when the response has arrived, continue with the callback. Though does this mean, that the code that was running while we waited for the server response, will have to finish itself of, or otherwise it will be interrupted?

Community
  • 1
  • 1
Ville Miekk-oja
  • 18,749
  • 32
  • 70
  • 106
  • 1
    How is this a duplicate of the other question? Because the title resembles that question's? – Jacob Jul 01 '16 at 02:53

4 Answers4

14

Javascript can run code asynchronously (i.e., "in the background") but not concurrently (i.e., "at the same time"). The difference is essentially that asynchronous JavaScript code will only run when there's no other code running.

Consider this example:

// print message asynchronously
setTimeout(function() {
  console.log('message');
}, 1000);

// infinite loop
while(true) { } // WARNING: if you actually try to run this, it will
                //          likely crash your browser...

If JavaScript had true concurrency, we would expect that message would be printed after 1000 ms. However, since JavaScript is merely asynchronous, it must wait until no other code is running; since it's stuck in an infinite loop, it will therefore never be able to run the code inside the setTimeout function.

Frxstrem
  • 38,761
  • 9
  • 79
  • 119
6

You may be confusing synchronicity with concurrency. JavaScript does not have concurrency, or running two execution threads at the same time; you have to spawn an entirely new JavaScript interpreter with things like Web Workers or run a cluster of workers in the case of Node to get concurrency.

However, it does have asynchronicity; you register callbacks for events that occur asynchronously, and the event loop calls those callbacks in the sequence they occur. Event callbacks are still non-concurrent, but that doesn't make JavaScript non-asynchronous.

Jacob
  • 77,566
  • 24
  • 149
  • 228
5

Notice there's a difference between concurrent and asynchronous code. When people say that JavaScript is not "truly asynchronous", they mean that there are no two lines of JavaScript code that will run simultaneously since it is unambiguously single-threaded.

However, it is an asynchronous language in the sense that some functions will execute and process in the background, then trigger a callback function or an event listener when data is ready. All while this is happening, other blocks of JavaScript can run, but again, not while any other lines of JavaScript are running.

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
1

They're talking about making async requests, usually to a server, or with event listeners. setInterval and setTimeout also disjoint and wait for the current function to finish


Example of callback (something to be called after completion)

myElement.addEventListener("mousedown", function (event) {
    console.log("this is a callback function and the listener event is:", event);
});

The more advanced, robust, and better way to write async is to use promises, where you can see the pattern easily, and pass your data as if it already exists. Promises are really separate wrappers of "promised data"

getPromisedMouseDownEvent.then(function (event) {
    console.log("this is a callback function and the listener event is:", event);
});

where the Promise defined is:

var getPromisedMouseDownEvent = new Promise(function (resolve, reject) {
    myElement.addEventListener("mousedown", function (event) {
        resolve(event);
    }
};

When you chain promises, you can separate them in a clean fashion, whereas callbacks are a little messier

var getPromisedData = new Promise(function (resolve) {
    resolve();
});
var getPromisedData2 = getPromisedData.then(function () {
    return new Promise(function (resolve) {
        resolve();
    });
});
var getPromisedData3 = getPromisedData2.then(function () {
    return new Promise(function (resolve) {
        resolve();
    });
});

You can also shorthand:

request1.then(request2).then(request3).then(function (data) {
    console.log(data);
});
neaumusic
  • 10,027
  • 9
  • 55
  • 83
  • 1
    I wouldn't say you can "treat promises as sequential". The only language construct that I'd say accomplishes a synchronous feel for asynchronous code is the proposed ES7 `async` and `await` keywords. Check [this](https://jakearchibald.com/2014/es7-async-functions/) out. – Patrick Roberts Jun 19 '16 at 18:44