Can someone explain JS Event Loop? - javascript

So I kind of understand the JS event loop, but still have a few questions. Here is my scenario and a few questions.
So let's say I have these functions:
function1 - reads an absolute huge file.
function2 - console.log("Hey");
function3 - console.log("What's up");
The way I am understanding this, and correct me if I'm wrong, what would happen is that the function1, function2, and function3, would be added to the queue. Then function1 would be added to the call stack followed by the next two functions.
Now the part where I'm confused is because the first function is going to take an extremely long time what happens to it? Does it get pushed somewhere else so that the next two functions are executed? I think the answer to this is that the only way it gets pushed somewhere else so that you can continue running is to make it an asynchronous function. And the way you make it a asynchronous function is either by using a callback function or promises. If this is the case how does it know that this is a asynchronous function? And where does it get pushed to so that the other two functions can be executed since they are relatively simple?
I think I answered the question myself but I keep confusing myself so if somebody could explain in extremely simple terms that would be great and sorry for the extremely stupid question.

Ordinary function calls are not pushed on the event queue, they're just executed synchronously.
Certain built-in functions initiate asynchronous operations. For instance, setTimeout() creates a timer that will execute the function asynchronously at a future time. fetch() starts an AJAX request, and returns a promise that will resolve when the response is received. addEventListener() creates a listener that will call the function when the specified event occurs on an element.
In all these cases, what effectively happens is that the callback function is added to the event queue when the corresponding condition is reached.
When one of these functions is called, it runs to completion. When the function returns, the event loop pulls the next item off the event queue and runs its callback, and so on.
If the event queue is empty, the event loop just idles until something is added. So when you're just starting at a simple web page, nothing may happen until you click on something that has an event listener, then its listener function will run.
In interactive applications like web pages, we try to avoid writing functions that take a long time to run to completion, because it blocks the user interface (other asynchronous actions can't interrupt it). So if you're going to read a large file, you use an API that reads it incrementally, calling an event listener for each block. That will allow other functions to run between processing of each block.
There's nothing specific that identifies asynchronous functions, it's just part of the definition of each function. You can't say that any function that has a callback argument is asynchronous, because functions like Array.forEach() are synchronous. And promises don't make something asychronous -- you can create a promise that resolves synchronously, although there's not usually a point to it (but you might do this as a stub when the caller expects a promise in the general case). The keyword async before a function definition just wraps its return value in a promise, it doesn't actually make it run asynchronously.

Related

What is the behaviour of callback execution in C# (assuming configure await is not set to false and assuming there is synchronization context)?

In Javascript, the callback (of the awaited async function) runs only when the call stack is empty. If there are multiple callbacks, then they are queued (in the event loop queue) such that only 1 callback runs in its entirety before the next callback gets change to run.
In case of C# (assuming ConfigureAwait is not set to false - that is - the callabck will run in the same thread; also assuming there is syncronization context [winforms]):
Does the callback run immediately without waiting for call stack to be empty?
Suppose there are multiple callbacks queued, then while 1 callback is running, and another callback is ready for execution, then does the running callback suspend while the new callback wants to run? Or is it sequential?
The answer is that it depends on the current SynchronizationContext and, if that is null, the current TaskScheduler.
When the awaited Task completes, and you have configured the Awaitable to capture the context and recover on it, then almost certainly that continuation cannot continue immediately (the thread is likely busy executing something else). All that can be done is to schedule the continuation for later execution on the current SynchronizationContext, which is done by calling SynchronizationContext.Post().
How this Post method is implemented depends on the SynchronizationContext (which is abstract). If you are using WPF, the SynchronizationContext is a DispatcherSynchronizationContext. There, Post is implemented by a call to Dispatcher.BeginInvoke() with DispatcherPriority.Normal.
In other words, your continuation gets queued on the dispatcher for later execution with normal priority. Other delegates may have higher priority (e.g. DispatcherPriority.Input), but eventually your delegate gets executed on the dispatcher.
Two things to notice:
BeginInvoke simply queues your delegate. It does not execute it right away. In other words, queuing your delegate is really fast.
The above explanation should illustrate why async-await is just syntactic sugar. You could achieve all these calls yourself, but the compiler does it for you, making your code flow more naturally.

Clarification on synchronous and asynchronous callbacks in javascript

iam currently working through the concept of callbacks and asynchronous programming in javascript. For that i read the corresponding chapters in the book "JavaScript" written by Philip Ackermann (ISBN:937-3-8362-5696-4).
But i have problems understanding the term asynchronous applied to callbacks used in examples of the book.
My current understand is that i can write synchronous callbacks like this:
function synchronousCallback(text, callback) {
//other code
callback(text);
}
synchronousCallback("End of function", console.log);
In the above example the callback is in my opinion only a nested function call. Nothing more.
But in a similar example of the book the author calls such a function asynchronous. See below the exact example of the book:
function asyncFunction(callbackFunction) {
//some code
console.log('Before callback');
callbackFunction();
console.log('After callback');
//some more code
}
function callbackFunction() {
console.log('called callback');
}
asyncFunction(callbackFunction);
My understanding of the code execution is that this callback would be executed as soon as the 'other code' is finished. The callback would not be added to the callback queue of the javascript engine and therefore be synchronous/blocking.
In my point of view a callback is asynchronous when used with setTimeout() or setInterval().
Maybe the example in the book is misleading or i misunderstood the term asynchronous in that case or i didnt not understand the execution order of such a callback scenario correctly.
Thanks for any help or clarification
There's nothing asynchronous about the example you gave.
Callbacks are asynchronous if the JavaScript event loop carries on running the rest of your program until an external factor (time passing in the case of setTimeout) triggers the callback.
Either the book is wrong, or you've not adequately expressed everything in the "similar" example it gave.
I have already mentioned the difference between synchronous and asynchronous behavior in JavaScript with this answer to your other question. I'll try to give you more details with this answer.
There, I recommended that you watch couple of talks about the subject. A talk by Philip Roberts, another talk by Jake Archibald or Jake's blog which explains the same. I'll try to summarize all of that.
All JavaScript code is synchronous and executes within a single thread. This means that there's one call stack and it can do one thing at a time. To better understand JavaScript runtime, please take a look at this image taken from MDN.
Let's try to go through your second example to see what's going on. When asyncFunction() gets called, it is pushed to stack (Jake calls them tasks, but based on MDN image, they are frames). Then, console.log('Before callback') is called and it gets pushed to stack on top of the current frame. So now, there's console.log on top and asyncFunction below.
console.log logs that string to console. Then, it's removed (popped) of the stack. asyncFunction is now on top of the stack. Now, callbackFunction() gets called and it is pushed to the stack, which then calls console.log('called callback') which also gets pushed to the stack.
Now, there are three functions on the stack: asyncFunction at the bottom, callbackFunction and console.log at top. When console.log finishes its job, it gets popped off the stack and now callbackFunction is also finished and that one also gets popped off the stack. Now, console.log('After callback') is called, pushed to the stack and popped after execution, which means that asyncFunction is finished and can be popped off the stack.
This is where all ends, the stack is empty, no more frames on it. Based on this and talks from the link above, there's nothing asynchronous in this example. A step by step is made by JS runtime and no asynchronous jumps are made here. But, how do we achieve concurrency in JS and do we need it? To quote Philip:
The reason we can do things concurrently is that the browser is more than just the runtime.
This is the reason why we can use setTimeout(() => { doSomething(); }, 5000) which would wait for 5(000 thousand milli)seconds without blocking (freezing) web page during that time. What happens when setTimeout is called? The browser starts another thread which runs in parallel. The thread's job is to only wait for 5 seconds. But, now it gets interesting what happens when the time's up.
To prevent concurrent modifications which might lead to unexpected behaviors, browsers have a queue mechanism. This allows the thread created by setTimeout to post a message to it and the message is, in this case, a function passed to setTimeout that will get executed once the message is processed.
But when are the messages processed? Well, just after no frames (tasks) are stacked. This means that messages are waiting for stack to get cleared after all frames are finished so that they can be processed. Messages are processed one at a time per one loop. Once message is taken as task it becomes regular JS code which gets executed on the same thread with the same rules for pushing and popping stack. Any other potential messages that are queued in the meantime must wait for the current message/frame to be processed.
setTimeout and setInterval are all parts of WebAPIs. Many (if not all) of them have asynchronous callbacks, and some examples include: DOM events, XHR events, Fetch events, Web workers, Web sockets, Promises, MutationObserver callbacks and so on. The last two (Promises and MutationObservers) schedule tasks on a different queue (microtask queue), but it's still asynchronous.
The difference between messages that are set to microtask queue and regular (or macrotask) queue is that the messages from macrotask queues are taken one at a time per event loop (which means that the whole loop needs to go around between two messages are processed), while messages from microtask queues are taken immediately after the stack is cleared. This means that they have higher priority than the ones on the macrotask queues. For more info, please watch/read Jake's talk/blog.
In my point of view a callback is asynchronous when used with setTimeout() or setInterval().
Yes, but not only with setTimeout() or setInterval(). If you set your callback to XMLHttpRequest's onreadystatechange function, it will be called asynchronously all the same.
Please note that there may be other APIs that require different set of function parameters than the ones from these examples - in fact, these examples aren't using function parameters at all.

angular js, broadcast an event and wait for it to complete

I have a an angular event like this:
$rootScope.$broadcast("postData");
doSomething();
however, doSomething() must wait for postData to complete before execution.
I would normally do something like:
$rootScope.$broadcast("postData").then(function(){
doSomething();
});
But apparently this isn't a thing in angular...Any ideas?
I would like to point-out that the previous solutions are not possible to be implemented where we don't have a handle on the async call to put a callback/promise/throw an event to solve the issue. The async call may be library function like for example setTimeout and we just cant use the previous solutions to fix the flow.
Here's my solution:
Put doSomething(); in an setTimeout with the time interval set to 0,
$rootScope.$broadcast("postData");
setTimeout(function(){
doSomething();}
, 0);
As simple as that!
settimeout makes dosomething() also to be asynchronous and this makes both the asynchronous operations happen one after the other(asynchronously). How? The explanation follows, but first note that the dosomething() is in a setTimout of interval 0 ms. One may obviously think that dosomething() shall be executed right-away (after 0 ms (actually default minimum time interval in javascript is 4 ms, so 0 ms becomes 4 ms)) before the postData event is broadcast-ed and serviced.
The answer is no!
Settimeout doesn't guarantee that the callback function passe inside it shall surely get executed after the specified interval. The specified interval is just the minimum interval needed after which the callback can be executed. SetTimeOut is an asynchronous call. if there are any other async operation waiting in the pipeline already, javascript runs them first.
For understanding how all this happen you need to understand what is an event loop in javascript.
Javascript runtime is single threaded, it just have one call stack, meaning it runs the code sequentially as it is written. Then how on earth does it implement asyncronicity?
So this is what happens under the hood when the javascript run-time encounters an operation that is asyncronous (like an API call, http call, settimeout, event broadcast etc). Please note these functions are not provided in our native javascipt run time engine (for example chromes V8 engine), instead they are provided by the browser (known as webAPIs), which are basically threads that you can make call to and they fork off an independent path of execution, separate from the javascript run-time execution flow, and thats how concurrency is actually achieved.
The question arises that Javascript run time is still single threaded. So how does these webAPI inturrpt the runtime flow and provide their results when they are complete? They can not just prompt the javascript runtime anytime when they are finished and provide their results to it? There must be some mechanism.
So javascript just makes the call to these webAPI's and does not wait for the output of the call. It simply goes on and execute the code that follows the call, and thats how the dosomething() in the problem, gets executed before the postDate event is listened and served).
Meanwhile the forked thread processes the http call or the setTimeout or handle the event etc, whatever the async call was made for. And when its done, the callback is pushed onto a event queue (task queue) (Note that multiple callback returns can be pushed into this queue.). But they are not run right away.
The javascript runtime waits for the call stack to get empty first. When there is nothing for the javascript runtime to execute the async calls callback function are popped out from the task queue, one by one and executed.
So in essence if we can just make dosomething() async, it will get executed after the 1st async is completed. Thats what I did. The settimeout callback gets pushed onto the event queue/task queue. Javascript call stack gets empty. The call back for postData event broadcast gets served. Then dosomething() gets a chance to execute.
You could $broadcast the event, listen for it in your other controller with $on, and $emit another event on completion, and listen for it in your original controller so you know when it is finished.
I would not recommend this approach. Instead use a service.
Emit and broadcast are coupling your mechanisms for communication to the view because the $scope is fundamentally a fabric for data-binding.
The services approach is far more maintainable and can communicate between services in addition to controllers.
Im assuming the broadcast of 'postData' is defining the end of a funciton.
If you use the $q angular service this can be accomplished easily by creating asynchronous functions.
function postData() {
var deferred = $q.defer();
//Do your asynchronous work here that post data does
//When the asynchronous work is done you can just resolve the defer or
//you can return data with resolve. Passing the data you want
//to return as a param of resolve()
deferred.resolve();
//return
return deferred.promise;
}
When you call postData now you can now use the then method to run doSomething() after postData() is done.
postData().then(function(data) {
doSomething();
}, function (err){
//if your ansyncronous function return defer.reject() instead of defer.resolve() you can catch the error here
};
Heres the angular documentation for $q
Heres a plunk to show you a simple example
This isn't how events works, you can't wait for events to complete.
Why won't you fire 'postData', let the consumers of this event do whatever they does, and then wait for another event and execute 'doSomething' once you receive it?
This way, once the consumer of 'postData' finish processing the event, he can fire another event which you can consume and execute your 'doSomething' when you receive it.

Is executing something asynchronously the same as pushing it to the back of the call stack?

"When there's nothing to do, check the queue. But only check the queue
when there's nothing left to do."
~ Javascript (https://www.youtube.com/watch?v=vMfg0xGjcOI)
So from what I understand, it basically means that you're delaying execution. Something like
SomeAsynchronousFunction();
SomeRegularFunction();
SomeOtherRegularFunction();
just means that you're essentially rearranging the tasks to
SomeRegularFunction();
SomeOtherRegularFunction();
SomeAsynchronousFunction();
in terms of how the bodies of the three functions are executed. Except that, if your browser/hardware supports parallel computing, and if the body of SomeAsynchronousFunction does not have any dependency on the other two functions, that it will be executed in parallel with the other two functions. Is that right? Or am I totally confused?
You're pretty close. But usually there will be some parts of SomeAsynchronousFunction that are synchronous, and those will be executed immediately -- it's only the completion of the function that's async. For instance, it might perform an AJAX call, so it first creates the XHR object, collects the parameters into a FormData object, and calls xhr.send() immediately; the asynchronous part is the execution of the onreadystatechange callback function, which happens when the server responds and the event processing loop has nothing else to do. So the actual order of execution is like this:
synchronous parts of SomeAsynchronousFunction();
SomeRegularFunction();
SomeOtherRegularFunction();
callback function from SomeAsynchronousFunction();
Javascript runs on a single thread, is non-blocking and uses what's called an event loop so your functions run in the original order, but the asynchronous calls, when they return add another message to the event loop and get executed when all other preceeding messages in the event loop are processed. For more info, I recommend reading this article from the Mozilla Developer Network, Concurrency model and Event Loop

When is JavaScript synchronous?

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?
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.
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.
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:
How JavaScript Timers Work
That article will help you to understand the single-threaded nature of JavaScript and how timers work internally and how asynchronous JavaScript execution works.
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.
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
"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?

Categories