244

I have been under the impression for that JavaScript was always asynchronous. However, I have learned that there are situations where it is not (ie DOM manipulations). Is there a good reference anywhere about when it will be synchronous and when it will be asynchronous? Does jQuery affect this at all?

Brian
  • 26,662
  • 52
  • 135
  • 170
  • 21
    Always with the exception of ajax. – defau1t Mar 19 '14 at 17:33
  • Accepted answer is wrong, and misleads, kindly check it. – Suraj Jain Dec 03 '17 at 08:24
  • 4
    Was also useful watching https://www.youtube.com/watch?v=8aGhZQkoFbQ to understand the event loop, and how the stack, web APIs, and the task queue work with regards to sync and async – mtpultz May 11 '18 at 07:07
  • 1
    @defau1t Isn't this wrong, JavaScript is always synchronous, when ajax call finishes the callback ends up in the queue, how is it an exception to synchronous nature of java script. – Suraj Jain Feb 10 '19 at 05:17

6 Answers6

336

JavaScript is always synchronous and single-threaded. If you're executing a JavaScript block of code on a page then no other JavaScript on that page will currently be executed.

JavaScript is only asynchronous in the sense that it can make, for example, Ajax calls. The Ajax call will stop executing and other code will be able to execute until the call returns (successfully or otherwise), at which point the callback will run synchronously. No other code will be running at this point. It won't interrupt any other code that's currently running.

JavaScript timers operate with this same kind of callback.

Describing JavaScript as asynchronous is perhaps misleading. It's more accurate to say that JavaScript is synchronous and single-threaded with various callback mechanisms.

jQuery has an option on Ajax calls to make them synchronously (with the async: false option). Beginners might be tempted to use this incorrectly because it allows a more traditional programming model that one might be more used to. The reason it's problematic is that this option will block all JavaScript on the page until it finishes, including all event handlers and timers.

Hardik Vaghani
  • 2,163
  • 24
  • 46
cletus
  • 616,129
  • 168
  • 910
  • 942
  • 32
    sorry, I didn't quite understand this statement "The code will stop executing until the call returns (successfully or in error)". could you elaborate. How can that statement be true when you also say "It won't interrupt any other code that's running"; Are you talking about callbacks code only in the first statement ? Please enlighten me. – krishna Dec 31 '12 at 17:52
  • Also notice [Is javascript guaranteed to be single-threaded?](http://stackoverflow.com/q/2734025/1048572) - the answer is No. – Bergi Feb 26 '13 at 16:22
  • 2
    Nettuts has a tutorial that's pretty good at explaining the basics of async here: http://net.tutsplus.com/tutorials/javascript-ajax/event-based-programming-what-async-has-over-sync/ – RobW Apr 27 '13 at 04:30
  • 29
    @cletus The statement "The code will stop executing until the call returns" needs correction because the execution doesn't stop. The code execution can continue. Otherwise, it would mean that the call is synchronous. – HS. Sep 16 '13 at 13:22
  • 1
    I didn't understand that statement too. – towry Nov 22 '13 at 15:29
  • "code will stop?" That will only happen if you make the ajax call synchronously. Lol but you mentioned not to do that as its a "beginner error and normal traditional model". Asynchronous behaviour roots from the fact that events can happen at unpredictable time and while the callback executes synchronously as there is only one thread, javascript would not sop executing as there could other events to be caught and added in the asynchronous event queue. Asynchronous is not tied to threads here but to events. Conceptual different. Hence the confusion. :) – Lakmal Caldera Dec 17 '14 at 01:34
  • "The code will stop executing until the call returns" is false, the code will keep executing _until_ the callback is fired. Unless, of course, you specify the `async: false` option, which as you said, is bad practice. – developius Jan 26 '16 at 19:51
  • 13
    This answer is incredibly misleading and confusing. Please see CMS' or Faraz Ahmad's answer instead. – iono Jul 15 '16 at 07:59
  • downvoting...because "The code will stop executing until the call returns (successfully or otherwise), at which point the callback will run synchronously" need correction. – Nikhil Mohanan May 19 '17 at 06:50
  • @cletus: _JavaScript is only asynchronous in the sense that it can make, for example, Ajax calls. The code will stop executing until the call returns (successfully or otherwise),..._ err..WHAT?! please change this (apparently) erroneous statement. This is the first piece of info that comes up when I search for _Is Javascript synchronous?_. This is awfully confusing and terribly misleading, seeing as the source if stackoverflow and most people take that as the truth at face-value. Thanks. – anotherDev Jul 05 '17 at 05:47
  • 2
    It's a shame this wrong and misleading answer has almost 200 upvotes. I tried making an edit, but it is rejected because it "deviates from the original intent of the post". "The code will stop executing until the call return". This is false. This answer should be edited or deleted. – Andrei Savin Oct 12 '17 at 14:23
  • Although this answer has some flaws, like the above comments show, this is perfect for a beginner, who will easily understand the essential. I'm not a beginner anymore, after nearly finishing my first JS extension for Chrome, but Faraz's answer, although technically correct, is harder to understand, even for me. This is concise, explanatory, and despite its flaws, easy to comprehend. – Yin Cognyto Dec 25 '17 at 20:43
  • @YinCognyto Google: Understanding Javascript: Weird Parts. – Suraj Jain Jan 24 '18 at 14:49
  • @Suraj Jain Yes, thank you - but my problem was not that I couldn't easily understand the technical part (so that I would have to read the book you mentioned), because I do understand it, having experienced other programming languages. This answer is easier to understand from a semantical point of view as well - that's why I said that it's perfect for beginners. The other answer sort of 'overcomplicates' things, that's all, and while that doesn't bother the more advanced users, it's an unnecessary obstacle for a beginner. – Yin Cognyto Jan 25 '18 at 16:45
  • @YinCognyto I meant that the answer below this is very great, as this has some fundamental flaws, I understood below answer but maybe because I alread knew about call stack from other language, I am now watching this lecture videos. Understanding JavaScript: Weird Parts, this is a course on udemy. And it is really good. – Suraj Jain Jan 26 '18 at 08:57
  • @iono Faraz who ? I don't see any answer by any Faraz – killjoy Aug 07 '18 at 19:40
  • @killjoy the comment you're replying to is 2 years old; please read timestamps before replying. Faraz's answer has presumably since been deleted, and Cletus' answer appears to have been improved by editing. – iono Aug 10 '18 at 05:34
  • 1
    @iono - I do read ts's - thats why I posted this so someone can update the answers. Who cares if it is 2 or 10 years old ? If this page shows up as #1 in google, it better be relevant and up-to-date right? Otherwise someone needs to flag this page and say 'not relevant' or 'please ignore, google bots' - as Quora tends to be doing. – killjoy Aug 10 '18 at 15:59
  • I know you do not answer comments, but can you answer this one time, I really have doubt in this things, can you clear my doubt, it will help me become a better developer. Thanks – Suraj Jain Oct 27 '18 at 09:35
  • @iono Faraz answer is the other one below this. the user has deleted his profile. Also make sure to watch "Understanding JavaScript Weird Parts", very beautiful course. – Suraj Jain Oct 27 '18 at 09:39
  • ok, now I understand js async and sync. after coding in js for around 2 years. this answer makes sense now. so in short `js is synchronous but when it comes to ajax its asynchronous` – ashen madusanka Aug 14 '21 at 03:05
  • The statement "The code will stop executing until the call returns" is incorrect because when an AJAX call is initiated, JS moves it to the Web APIs and the call stack will execute the remaining statements (if any). Now when the AJAX call is complete, it moves to the Event Queue where Event Loop moves it to the Call Stack for the execution of the callback. The same happens with `setTimeout`. This flow is still synchronous but Web APIs made it look asynchronous – Haseeb Anwar Dec 16 '21 at 10:13
291

JavaScript is single threaded and has a synchronous execution model. Single threaded means that one command is being executed at a time. Synchronous means one at a time i.e. one line of code is being executed at time in order the code appears. So in JavaScript one thing is happening at a time.

Execution Context

The JavaScript engine interacts with other engines in the browser. In the JavaScript execution stack there is global context at the bottom and then when we invoke functions the JavaScript engine creates new execution contexts for respective functions. When the called function exits its execution context is popped from the stack, and then next execution context is popped and so on...

For example

function abc()
{
   console.log('abc');
}


function xyz()
{
   abc()
   console.log('xyz');
}
var one = 1;
xyz();

In the above code a global execution context will be created and in this context var one will be stored and its value will be 1... when the xyz() invocation is called then a new execution context will be created and if we had defined any variable in xyz function those variables would be stored in the execution context of xyz(). In the xyz function we invoke abc() and then the abc() execution context is created and put on the execution stack... Now when abc() finishes its context is popped from stack, then the xyz() context is popped from stack and then global context will be popped...

Now about asynchronous callbacks; asynchronous means more than one at a time.

Just like the execution stack there is the Event Queue. When we want to be notified about some event in the JavaScript engine we can listen to that event, and that event is placed on the queue. For example an Ajax request event, or HTTP request event.

Whenever the execution stack is empty, like shown in above code example, the JavaScript engine periodically looks at the event queue and sees if there is any event to be notified about. For example in the queue there were two events, an ajax request and a HTTP request. It also looks to see if there is a function which needs to be run on that event trigger... So the JavaScript engine is notified about the event and knows the respective function to execute on that event... So the JavaScript engine invokes the handler function, in the example case, e.g. AjaxHandler() will be invoked and like always when a function is invoked its execution context is placed on the execution context and now the function execution finishes and the event ajax request is also removed from the event queue... When AjaxHandler() finishes the execution stack is empty so the engine again looks at the event queue and runs the event handler function of HTTP request which was next in queue. It is important to remember that the event queue is processed only when execution stack is empty.

For example see the code below explaining the execution stack and event queue handling by Javascript engine.

function waitfunction() {
    var a = 5000 + new Date().getTime();
    while (new Date() < a){}
    console.log('waitfunction() context will be popped after this line');
}

function clickHandler() {
    console.log('click event handler...');   
}

document.addEventListener('click', clickHandler);


waitfunction(); //a new context for this function is created and placed on the execution stack
console.log('global context will be popped after this line');

And

<html>
    <head>

    </head>
    <body>

        <script src="program.js"></script>
    </body>
</html>

Now run the webpage and click on the page, and see the output on console. The output will be

waitfunction() context will be popped after this line
global context will be emptied after this line
click event handler...

The JavaScript engine is running the code synchronously as explained in the execution context portion, the browser is asynchronously putting things in event queue. So the functions which take a very long time to complete can interrupt event handling. Things happening in a browser like events are handled this way by JavaScript, if there is a listener supposed to run, the engine will run it when the execution stack is empty. And events are processed in the order they happen, so the asynchronous part is about what is happening outside the engine i.e. what should the engine do when those outside events happen.

So JavaScript is always synchronous.

  • 1
    Of course this requires you read a bit about execution context stack, and only the the addition of it being empty and event que makes me finally feel like I understand java script excution deterministically. What's worse is I feel it only takes a page of reading yet I find it hardly anywhere. So why nobody just say it? Either they don't know or what? But I feel if a js tutorial had this it could have saved me alot of time. >:| – marshal craft Sep 08 '17 at 16:18
  • I recognize Anthony Alicea Udemy course in your explaination.I also took 'Javascript weird part' course and the working of the Javascript engine is very well explained – Christian LSANGOLA Dec 27 '18 at 11:38
  • I find this presentation really helpful as well: https://www.youtube.com/watch?v=8aGhZQkoFbQ – johan Sep 27 '20 at 13:41
  • Sorry, but for me the first paragraph is everything but clear. – kaiserlautern Jul 01 '21 at 15:16
107

JavaScript is single-threaded, and all the time you work on a normal synchronous code-flow execution.

Good examples of the asynchronous behavior that JavaScript can have are events (user interaction, Ajax request results, etc) and timers, basically actions that might happen at any time.

I would recommend you to give a look to the following article:

That article will help you to understand the single-threaded nature of JavaScript and how timers work internally and how asynchronous JavaScript execution works.

async

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
18

To someone who really understands how JS works this question might seem off, however most people who use JS do not have such a deep level of insight (and don't necessarily need it) and to them this is a fairly confusing point, I will try to answer from that perspective.

JS is synchronous in the way its code is executed. each line only runs after the line before it has completed and if that line calls a function after that is complete etc...

The main point of confusion arises from the fact that your browser is able to tell JS to execute more code at anytime (similar to how you can execute more JS code on a page from the console). As an example JS has Callback functions who's purpose is to allow JS to BEHAVE asynchronously so further parts of JS can run while waiting for a JS function that has been executed (I.E. a GET call) to return back an answer, JS will continue to run until the browser has an answer at that point the event loop (browser) will execute the JS code that calls the callback function.

Since the event loop (browser) can input more JS to be executed at any point in that sense JS is asynchronous (the primary things that will cause a browser to input JS code are timeouts, callbacks and events)

I hope this is clear enough to be helpful to somebody.

hatef
  • 5,491
  • 30
  • 43
  • 46
Yehuda Schwartz
  • 3,378
  • 3
  • 29
  • 38
12

Definition

The term "asynchronous" can be used in slightly different meanings, resulting in seemingly conflicting answers here, while they are actually not. Wikipedia on Asynchrony has this definition:

Asynchrony, in computer programming, refers to the occurrence of events independent of the main program flow and ways to deal with such events. These may be "outside" events such as the arrival of signals, or actions instigated by a program that take place concurrently with program execution, without the program blocking to wait for results.

non-JavaScript code can queue such "outside" events to some of JavaScript's event queues. But that is as far as it goes.

No Preemption

There is no external interruption of running JavaScript code in order to execute some other JavaScript code in your script. Pieces of JavaScript are executed one after the other, and the order is determined by the order of events in each event queue, and the priority of those queues.

For instance, you can be absolutely sure that no other JavaScript (in the same script) will ever execute while the following piece of code is executing:

let a = [1, 4, 15, 7, 2];
let sum = 0;
for (let i = 0; i < a.length; i++) {
    sum += a[i];
}

In other words, there is no preemption in JavaScript. Whatever may be in the event queues, the processing of those events will have to wait until such piece of code has ran to completion. The EcmaScript specification says in section 8.4 Jobs and Jobs Queues:

Execution of a Job can be initiated only when there is no running execution context and the execution context stack is empty.

Examples of Asynchrony

As others have already written, there are several situations where asynchrony comes into play in JavaScript, and it always involves an event queue, which can only result in JavaScript execution when there is no other JavaScript code executing:

  • setTimeout(): the agent (e.g. browser) will put an event in an event queue when the timeout has expired. The monitoring of the time and the placing of the event in the queue happens by non-JavaScript code, and so you could imagine this happens in parallel with the potential execution of some JavaScript code. But the callback provided to setTimeout can only execute when the currently executing JavaScript code has ran to completion and the appropriate event queue is being read.

  • fetch(): the agent will use OS functions to perform an HTTP request and monitor for any incoming response. Again, this non-JavaScript task may run in parallel with some JavaScript code that is still executing. But the promise resolution procedure, that will resolve the promise returned by fetch(), can only execute when the currently executing JavaScript has ran to completion.

  • requestAnimationFrame(): the browser's rendering engine (non-JavaScript) will place an event in the JavaScript queue when it is ready to perform a paint operation. When JavaScript event is processed the callback function is executed.

  • queueMicrotask(): immediately places an event in the microtask queue. The callback will be executed when the call stack is empty and that event is consumed.

There are many more examples, but all these functions are provided by the host environment, not by core EcmaScript. With core EcmaScript you can synchronously place an event in a Promise Job Queue with Promise.resolve().

Language Constructs

EcmaScript provides several language constructs to support the asynchrony pattern, such as yield, async, await. But let there be no mistake: no JavaScript code will be interrupted by an external event. The "interruption" that yield and await seem to provide is just a controlled, predefined way of returning from a function call and restoring its execution context later on, either by JS code (in the case of yield), or the event queue (in the case of await).

DOM event handling

When JavaScript code accesses the DOM API, this may in some cases make the DOM API trigger one or more synchronous notifications. And if your code has an event handler listening to that, it will be called.

This may come across as pre-emptive concurrency, but it is not: it is the JavaScript code that initiates the API call, and thus controls that the API can do some stuff, but this is just like a function call: once your event handler(s) return(s), the DOM API will eventually also return, and the original JavaScript code will continue after the API call it made.

In other cases the DOM API will just dispatch an event in the appropriate event queue, and JavaScript will pick it up once the call stack has been emptied.

See synchronous and asynchronous events

trincot
  • 317,000
  • 35
  • 244
  • 286
  • "and the original JavaScript code will continue" this sounds as if the original js code has been interrupted, while previously we learned that it's never interrupted. Could you elaborate? – ZenVentzi Oct 06 '22 at 10:48
  • The difference with pre-emptive interruption is that it is the JavaScript code that dictates when the DOM API will do something (in the context of where you quote from). It is like a function call initiated by the JavaScript code, but then calling an API that is not JavaScript implemented. With pre-emptive concurrency, code execution could be interrupted at any time to give some other code some execution time. This is not how it works in JavaScript. – trincot Oct 06 '22 at 10:53
3

"I have been under the impression for that JavaScript was always asynchronous"

You can use JavaScript in a synchronous way, or an asynchronous way. In fact JavaScript has really good asynchronous support. For example I might have code that requires a database request. I can then run other code, not dependent on that request, while I wait for that request to complete. This asynchronous coding is supported with promises, async/await, etc. But if you don't need a nice way to handle long waits then just use JS synchronously.

What do we mean by 'asynchronous'. Well it does not mean multi-threaded, but rather describes a non-dependent relationship. Check out this image from this popular answer:

         A-Start ------------------------------------------ A-End   
           | B-Start -----------------------------------------|--- B-End   
           |    |      C-Start ------------------- C-End      |      |   
           |    |       |                           |         |      |
           V    V       V                           V         V      V      
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->| 

We see that a single threaded application can have async behavior. The work in function A is not dependent on function B completing, and so while function A began before function B, function A is able to complete at a later time and on the same thread.

So, just because JavaScript executes one command at a time, on a single thread, it does not then follow that JavaScript can only be used as a synchronous language.

"Is there a good reference anywhere about when it will be synchronous and when it will be asynchronous"

I'm wondering if this is the heart of your question. I take it that you mean how do you know if some code you are calling is async or sync. That is, will the rest of your code run off and do something while you wait for some result? Your first check should be the documentation for whichever library you are using. Node methods, for example, have clear names like readFileSync. If the documentation is no good there is a lot of help here on SO. EG:

How to know if a function is async?

cham
  • 8,666
  • 9
  • 48
  • 69