I was recently tinkering with node js and its asynchronous nature and came across something weird. Here is the code -
let sum = 0;
for(let i=0;i<10000000000;i++){
sum += i
if(i==99999999){
console.log(sum);
}
}
console.log('abc');
By definition of non blocking,it should not wait for the for loop results and should print 'abc' first and then print the value of sum after completion of calculation right? However,this is not happening and the program is waiting for the for loop to finish and print the value of sum and then print 'abc'. Could anyone explain the reasoning behind this? Is this happening due to the way console.log works?
Its non blocking for IO operations, IO operations include file read write, network read write, database read write etc.
This is controlled by event loop.
For loop is not IO operation, however if you have IO operation inside for loop you will get the non blocking taste.
You can read more here https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/
Javascript works synchronouse. There are few things that work asynchronouse:
setImmediate, setTimeout(), and promises like fetch(), Promise.resolve() etc.
I also need to mention that the callback from the setTimeout for example is getting added to an task que or also named "callback que" and its waiting till the event loop is done with its synchronouse code. After the event loop is ready it will take this callback and add it to the callstack and execute that callback function. And this code will be executed synchronouse.
There is actually no true parallelism. For that you should use web workers.
Related
var identifier = '0';
var serviceCodes = parseServiceCodes(identifier);
console.log(serviceCodes);
function parseServiceCodes(id){
var serviceCodes = id + 'HYJSIXNS';
return serviceCodes
}
0HYJSIXNS is returned in the console. But I thought that since JavaScript is asynchronous, the variable would be assigned before the function is returned, making it null.
Javascript isn't asynchronous by default, and code is executed in order unless you specify that it shouldn't be. You're never making a call to an external resource, so there's nothing to be async here.
JS, like any interpreted language, is run line-by-line. In your example, at the parseServiceCodes callsite, execution goes from line 2 (the callsite) to line 6 (the function body).
Async behavior is introduced for time consuming operations, like HTTP requests. In this case, the expensive function either takes a callback parameter (code to run once the expensive operation is over) or returns a Promise which "resolves" with the computed data when ready.
To illustrate the first case, let's say we have a function getFromServer which needs a URI and a callback:
function getFromServer(uri, callback){ // ...
It doesn't matter exactly what happens under the hood, just that execution is given back to the main program after invocation. This means the program isn't blocked for the duration of this expensive operation. When getFromServer is done, it will come back and call callback with some data.
To learn more about the second case, Promises, I encourage you to read the documentation I linked to earlier in this response.
You seem to misunderstand what it means to say that "JavaScript is asynchronous".
JavaScript is asynchronous because it supports and benefits from usage of asynchronicity, which is considered a common design pattern throughout the language by using features such as asynchronous callbacks, promises and even async/await, but this does not mean that all code is asynchronous.
You can easily write synchronous code, as you just demonstrated in your question, and there is no issue specifying a return value that is not a Promise.
This is because the code invoking it expects the return value to contain a string, which it then assigns to serviceCodes and uses that in the same tick.
If any of these terms above confuse you, please refer to their respective documentation and usage I've provided the links for.
I'm tying to call two functions in JavaScript when a button click event happens.
<button type="submit" id="mySubmit" onClick="submitInput();getAll()">Search</button>
So I wondered what function will call first. And I have no idea.
Will the submitInput() executes first or getAll() or both executes at the same time concurrently. ?
It executes the same way as ordinary javascript. submitInput() executes first. I would not reccomend doing it this way though. It would be considered bad practice. keep your javascript out of your HTML ok.
Lastly, just because something executes first, does not mean that it will finish first.. javascript is both async and synchronous in some cases.
JavaScript is by nature mono-thread, that is to say its engine can only compute one operation at once (it is not parallel !). It means that as long as a process is not finished, the user remains stuck in front of his browser and has to wait till the end. Theoritically :)
Fortunately, JS is also asynchronous, it means that one is able to free the user thread, waiting for some other conditions to be fullfilled to continue the computation. To be more accurate, the execution of some functions can be delayed, one of the simplest examples is the use of the functions setTimeout() (once) or setInterval() (several times). A callback is a function triggered only under some conditions (i.e. a time interval expires, a script sends an answer, etc...). It prevents the browser from being "freezed", waiting for the result of a computation.
In your case, if there isn't any asynchronous call, the functions will be executed in the order you gave. Once the first is completed, the second will be triggered.
Try those two dummy functions :
function myFunction() {
for (var iter = 0; iter < 500000000; iter++) {
if (iter==499999999) {alert ("done !");}
}
}
function myFunction2() {
alert ("Hi there !");
}
Call them in this order, then change their order. The second will always be executed once the first is complete.
The Error in JavaScript internal/external file also stops the below code
For example:
var myObj = {};
myObj.other.getName = function(){
console.log('other is not defined');
};
alert('this will not show');
in above code, the alert will not come as the above code has error.
I added the same code in one file tst1.js and below this add one more file tst2.js. put alert('in tst2.js') in it. the tst2 alert come while tst1 not. it is some what related to
code compilation/interpretation.
It's much appreciated If someone explain me this behavior :)
This is the default behaviour of JavaScript. Avoid errors and the code will run normally.
Also you can handle errors with try...catch: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
All JS implementations are, AFAIK, single threaded. This means that all of your code is executed sequentially, on a single thread (logically). If this thread encounters a fatal error, it grinds to a halt. All code that comes after the point where the error occurs is ignored (the JS engine halted, no work is done anymore).
To clarify: it does not matter how many files you have. All of the JS code is stringed together into one big script, and this one script is executed sequentially (execution point starts at line 1 of the first script, and ends at the last line of the last script). Any errors in that code will cause the overall execution to grind to a halt:
//file1.js
var foo = (function()
{
console.log('This file is flawless, but pointless');
}());
//file2.js
foo();//calls previously defined function, assigned to var foo
//file3.js
fudhfsiufhi;//ERROR
//file4.js
foo();//will never get executed, because an error occurred in file3.js
Remove file3, or indeed fix the error, and everything will work as expected.
Allthough JS code is executed/evaluated sequentially, event handlers, callbacks, intervals, and timeouts might lead you to believe otherwise. Couple that with the fact that you have some control over what code is executed when, but not full control, and you get situations that, at first, seem rather counter intuitive. Consider this:
setTimeout(function()
{
massive(syntaxError) -123 + "here";
},0);//zero MS
alert('This will show');
This oddity is well documented, but it has to do with JS having a callback/handler loop, and queue. The setTimeout sets a timeout, to call the anonymous function in 0ms (immediately), but that callback is sent to the queue, which is checked periodically. Before the queue is checked (and the callback invoked), the alert will show. That's why the interval you pass to setTimeout or setInterval is not guaranteed to be exactly N milliseconds.
You can postpone a call to a method somewhat, by adding a call to the queue, like in the snippet above. But when the queue is processed, and what order the queued calls will be performed in are things you have no real say in. No say whatsoever.
It doesn't matter how many files, or how many statements that come before or after the problematic piece of code: there is no thread left to carry on.
The code you posted has a pretty clear error in it: you're assigning a property to other (a property of myObj, but this property is not defined anywhere, let alone defined as an object. Fix it by declaring properties first, before accessing them:
var myObj = {other: {}};//other is an empty object literal
myObj.other.getName = function()
{
console.log('This works');
};
alert('And the alert will show');
Your current code evalutes to:
var myObj = {};//object
var (myObj.other).getName = ...;
//evaluates to undefined
undefined.getName = ...//ERROR
undefined is a primitive value, actually signifying the absence of a value. undefined, therefore, cannot be accessed as an object, it can't be assigned properties.
Note:
This is just for completeness' sake, but JS is indeed single-threaded most of the time, but ECMAScript5 introduced Worker's which allow for some restricted form of multi-threading (without shared state, for example). Read through the MDN documentation on workers if you want to know more.
I thought I would try and be clever and create a Wait function of my own (I realise there are other ways to do this). So I wrote:
var interval_id;
var countdowntimer = 0;
function Wait(wait_interval) {
countdowntimer = wait_interval;
interval_id = setInterval(function() {
--countdowntimer <=0 ? clearInterval(interval_id) : null;
}, 1000);
do {} while (countdowntimer >= 0);
}
// Wait a bit: 5 secs
Wait(5);
This all works, except for the infinite looping. Upon inspection, if I take the While loop out, the anonymous function is entered 5 times, as expected. So clearly the global variable countdowntimer is decremented.
However, if I check the value of countdowntimer, in the While loop, it never goes down. This is despite the fact that the anonymous function is being called whilst in the While loop!
Clearly, somehow, there are two values of countdowntimer floating around, but why?
EDIT
Ok, so I understand (now) that Javascript is single threaded. And that - sort of - answers my question. But, at which point in the processing of this single thread, does the so called asynchronous call using setInterval actually happen? Is it just between function calls? Surely not, what about functions that take a long time to execute?
There aren't two copies of the variable lying around. Javascript in web browsers is single threaded (unless you use the new web workers stuff). So the anonymous function never has the chance to run, because Wait is tying up the interpreter.
You can't use a busy-wait functions in browser-based Javascript; nothing else will ever happen (and they're a bad idea in most other environments, even where they're possible). You have to use callbacks instead. Here's a minimalist reworking of that:
var interval_id;
var countdowntimer = 0;
function Wait(wait_interval, callback) {
countdowntimer = wait_interval;
interval_id = setInterval(function() {
if (--countdowntimer <=0) {
clearInterval(interval_id);
interval_id = 0;
callback();
}
}, 1000);
}
// Wait a bit: 5 secs
Wait(5, function() {
alert("Done waiting");
});
// Any code here happens immediately, it doesn't wait for the callback
Edit Answering your follow-up:
But, at which point in the processing of this single thread, does the so called asynchronous call using setInterval actually happen? Is it just between function calls? Surely not, what about functions that take a long time to execute?
Pretty much, yeah — and so it's important that functions not be long-running. (Technically it's not even between function calls, in that if you have a function that calls three other functions, the interpreter can't do anything else while that (outer) function is running.) The interpreter essentially maintains a queue of functions it needs to execute. It starts starts by executing any global code (rather like a big function call). Then, when things happen (user input events, the time to call a callback scheduled via setTimeout is reached, etc.), the interpreter pushes the calls it needs to make onto the queue. It always processes the call at the front of the queue, and so things can stack up (like your setInterval calls, although setInterval is a bit special — it won't queue a subsequent callback if a previous one is still sitting in the queue waiting to be processed). So think in terms of when your code gets control and when it releases control (e.g., by returning). The interpreter can only do other things after you release control and before it gives it back to you again. And again, on some browsers (IE, for instance), that same thread is also used for painting the UI and such, so DOM insertions (for instance) won't show up until you release control back to the browser so it can get on with doing its painting.
When Javascript in web browsers, you really need to take an event-driven approach to designing and coding your solutions. The classic example is prompting the user for information. In a non-event-driven world, you could do this:
// Non-functional non-event-driven pseudo-example
askTheQuestion();
answer = readTheAnswer(); // Script pauses here
doSomethingWithAnswer(answer); // This doesn't happen until we have an answer
doSomethingElse();
That doesn't work in an event-driven world. Instead, you do this:
askTheQuestion();
setCallbackForQuestionAnsweredEvent(doSomethingWithAnswer);
// If we had code here, it would happen *immediately*,
// it wouldn't wait for the answer
So for instance, askTheQuestion might overlay a div on the page with fields prompting the user for various pieces of information with an "OK" button for them to click when they're done. setCallbackForQuestionAnswered would really be hooking the click event on the "OK" button. doSomethingWithAnswer would collect the information from the fields, remove or hide the div, and do something with the info.
Most Javascript implementation are single threaded, so when it is executing the while loop, it doesn't let anything else execute, so the interval never runs while the while is running, thus making an infinite loop.
There are many similar attempts to create a sleep/wait/pause function in javascript, but since most implementations are single threaded, it simply doesn't let you do anything else while sleeping(!).
The alternative way to make a delay is to write timeouts. They can postpone an execution of a chunk of code, but you have to break it in many functions. You can always inline functions so it makes it easier to follow (and to share variables within the same execution context).
There are also some libraries that adds some syntatic suggar to javascript making this more readable.
EDIT:
There's an excelent blog post by John Resig himself about How javascript timers work. He pretty much explains it in details. Hope it helps.
Actually, its pretty much guaranteed that the interval function will never run while the loop does as javascript is single-threaded.
There is a reason why no-one has made Wait before (and so many have tried); it simply cannot be done.
You will have to resort to braking up your function into bits and schedule these using setTimeout or setInterval.
//first part
...
setTimeout(function(){
//next part
}, 5000/*ms*/);
Depending on your needs this could (should) be implemented as a state machine.
Instead of using a global countdowntimer variable, why not just change the millisecond attribute on setInterval instead? Something like:
var waitId;
function Wait(waitSeconds)
{
waitId= setInterval(function(){clearInterval(waitId);}, waitSeconds * 1000);
}
There is array of objects, which are expanded with parallel ajax requests. When last request is done array should be processed. The only solution i see is:
function expandArray(objects, callback){
number_of_requests=objects.length-1;
for(i in objects){
$.getJSON(request,function(){
//expanding array
if(--number_of_reuests==0){
callback();
}
});
}
}
But as requests are executed in parallel there is chance of race condition. Variable number_of_requests can be edited by two "threads" simultaneously. How to avoid chance of race condition?
Is it possible to rework your AJAX so that it all goes in one request? That part of the system will be the biggest bottleneck and can get tricky (as you've found out), so the less requests you make, the better.
The only other way I could think would be if each request mutated its related object, setting a flag value or something, and then you looped through all the objects to check if all the flags had been set yet.
Isn't Javascript single threaded? The kind of condition you talk of wouldn't occur.
It's more complex, but I would suggest using a third function to monitor the results. Something like this:
1) Start monitor - using an appropriate interval monitor (using an interval to test here is important - a simple loop would lock the JS engine up tight) the results of requests A and B.
2) Call request A.
3) Call request B.
4) Request B finishes - callback function sets a "B All Done!" value.
5) Request A finishes - callback function sets an "A All Done!" value.
6) Monitor recognizes that both requests are completed and calls function which uses data from both.
Worded more simply this is "dependencies" (multiple calls)to "monitor" (the function that checks dependencies) to "completion" (the action to take when all is ready).
You can create the callbacks and the completion function as nested functions to maintain encapsulation and reduce "little" in the global scope.
You can extend your dependencies as far as you like.