1

I have tryed to find answer on web, and did it partly. But I still can not completely understand how JS can run ansyncronous code?

My seeing of things:

JS give us ability of asyncronous programming. That means that we can start first task, then while one is in progress we can start second task, etc. Before js can start second task it should be freed from the previous task. It can be achived with 2 ways:

  • js by its own end the task (the code which should be processed by js only)
  • js can start the task which should be processed by filesystem for example. In this case js, do its work, pass the task to filesystem and starts to process other queued tasks. When js is freed and filesystem have returned the result, js can continue that task.

So we can not achive asyncronous by just writing the next code:

function doSth( callback ) {
    let arr = [];

    for ( let i=1e6; i > 0; i-- )
        arr.push( i );

    callback();
}

doSth( console.log.bind( null, 'I am callback' );
console.log( 'just a line' );

due to doSth() contains only js's work it will be completed first and then just appear 'just a line'? So it is not asyncronously, right? But if we will have filesystem task insted of loop, we will have asyncronous function?

And one more question: Are promises really asyncronous? How can they be asyncronous (i mean, can other tasks be processed at the time of promise processing), either promises just mimics asyncronous code? *I know, there is additional queue for promises.

Maby I just don't understand some base? I'll be glad if you can explain me to make my questions more explictly for me.

Liam
  • 27,717
  • 28
  • 128
  • 190
  • 1
    Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Liam Sep 19 '17 at 08:35
  • also [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Liam Sep 19 '17 at 08:36
  • Possible duplicate of [How does Asynchronous Javascript Execution happen? and when not to use return statement?](https://stackoverflow.com/questions/7104474/how-does-asynchronous-javascript-execution-happen-and-when-not-to-use-return-st) – anteAdamovic Sep 19 '17 at 08:42
  • Your right BTW to say that the code you've posted is not asynchronous. – Liam Sep 19 '17 at 08:54
  • @Liam, I'll dublicate my question ( I think, you have not noticed it): I think I just now understand that I had uncorrect meaning of asyncronous. Does asyncronous means in simple words: "hey, js, take this function, but you should do nothing now with it. But call it when it'll be needed"? – Vadim Cherepenichev Sep 19 '17 at 08:57
  • erm...yes(ish). Asyncronous means in simple words, "hey js, Here's an async function (only things like ajax calls are async, everything else is sync). It'll take a while as it's using external resources (like HTTP), don't wait for that external call to come back as it'll slow you down, fire it, then when it's finished run this method. While your waiting carry on processing this stuff underneath." That's about as simple as I can make it. [Here's a better analogy](https://stackoverflow.com/a/23929676/542251) – Liam Sep 19 '17 at 08:59
  • @Liam, thank you ;) – Vadim Cherepenichev Sep 19 '17 at 09:26

2 Answers2

0

Watch this playlist for a light overview of asynchronous Javascript.

But if you really want to understand all the details, read this book.

To answer one of your main questions, asynchrony has nothing to do with the filesystem. It's all Javascript still. To quote the book I recommended:

Asynchrony is "when part of your program runs now, and another part of your program runs later -- there's a gap between now and later where your program isn't actively executing."

Consider your code:

function doSth(callback) {
  let arr = [];
  for (let i=1e6; i > 0; i--){
    arr.push(i);
  }
  callback();
}

doSth(console.log.bind(null, 'I am callback'));
console.log('just a line');

This will output

I am callback

Then

just a line

However, if you changed your code to this:

function doSth(callback) {
  let arr = [];
  for (let i=1e6; i > 0; i--){
    arr.push(i);
  }
  setTimeout(callback, 0);
}

doSth(console.log.bind(null, 'I am callback'));
console.log('just a line');

You will get

just a line

Then

I am callback

It essentially has to do with what function is calling your callback. "doSth" is not an asynchronous function, no matter how long the for loop will take. In the second example, however, setTimeout is the function that's calling your callback, and setTimeout is an asynchronous function that runs after the rest of your synchronous code just because that's the way it's intended to work. Another common asynchronous function would be any sort of AJAX request, and the callback provided to it would also be called after any other synchronous code.

  • so, asyncrony is just: start task -> pause task -> continue task? – Vadim Cherepenichev Sep 19 '17 at 08:37
  • 2
    This is very misleading and vague. – Liam Sep 19 '17 at 08:38
  • 1
    No @VadimCherepenichev it's more like [time slicing](https://en.wikipedia.org/wiki/Preemption_(computing)#Time_slice). Javascript is essentially single threaded. So it never waits for external calls. It just continues, you then need to handle the response form the external call in a separate process, this will get scheduled to run on the single thread once it returns.It's all covered in the duplicates I highlighted above – Liam Sep 19 '17 at 08:40
  • @Liam, yes I know that is single threaded. So you mean that js just stop at some point of the function. And then add the rest actions like a new task to the end of the que (or set timer), and continue after appropriate time? – Vadim Cherepenichev Sep 19 '17 at 08:45
  • @Liam, I think I just now understand that I had uncorrect meaning of asyncronous. Does asyncronous means in simple words: "hey, js, take this function, but you should do nothing now with it. But call it when it'll be needed"? – Vadim Cherepenichev Sep 19 '17 at 08:55
  • I mean it's better – Liam Sep 19 '17 at 09:02
0

I think you have it right.

The function doSth is synchronous and will block the main thread until it's finished. You only provide callback API, but that does not mean it will magically become asynchronous.

Truth is, all JS code you write is synchronous unless you use core JS functions that are defined as asynchronous (e.g., fs.readFile, setTimeout, $.ajax({...}).done). Without them, you can't create asynchronous behavior, you would have to write your own JS core from scratch, with event loop (in fact, I encourage you to google and study what the javascript event loop is, I believe it will clarify many things for you and will give you a much better idea of what is happening in the core). All 3rd party libs out there achieve asynchronous behavior simply because they use these core functions and wrap them with their own code, providing more elegant and higher-level APIs.

The same applies for promises. Yes they are asynchronous, BUT ONLY if you fill them with asynchronous code. Indeed, they have some extra overhead and do not run the code immediately, but if a single promise contains only synchronous code then its eventual execution will block the main thread until it's finished.

dzuremar
  • 170
  • 8