0

I'm brand new to node and trying to wrap my head around callbacks and how to use them. If i'm understanding correct, you can use callbacks as a way to unblock your code so that functions that may take a while to execute won't get in the way of anything that comes after. I'm trying an example that I made up on my own and can't get it to work right.

In this example, the recursive function will take a few seconds to complete. How would you write the callback so that the system console logs 1, then 2, then the answer to the cursive function to show that the recursive function isn't blocking anything afterward?

function recursive(n) {
  if(n <= 2) {
    return 1;
  } else {
    return recursive(n - 1) + recursive(n - 2);
  }
};

console.log(1);

console.log(recursive(42))


console.log(2);
xeroshogun
  • 1,062
  • 1
  • 18
  • 31
  • "*you can use callbacks as a way to unblock your code*" - [No](http://stackoverflow.com/q/21884258/1048572). You can use asynchronous functions (that take callbacks) to unblock your code. – Bergi Mar 09 '16 at 05:02

3 Answers3

1

node.js has no built in way of making synchronous code suddenly become asynchronous or non-blocking. node.js uses callbacks to notify completion or status from operations that are actually asynchronous in their implementation such as async file or disk I/O or networking.

So, in short, you can't just add a callback to your function and magically make it asynchronous or non-blocking.

To make it non-blocking, you would have to move it to another process and let that process run the operation and then have that process communicate back asynchronously to this process (via some interprocess communication). That other process could be another node.js process or it could be an application in any other language.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

Not how it works. First of all, JavaScript is single-threaded. This means, while the processor is busy processing JavaScript, you can't execute more JavaScript at the same time. The blocking that is avoided by callbacks is time where one would normally be waiting for other things: the disk, the database, the network, the remote client, another process, user input, a delayed function call...

The way this works is: you say you want to, say, read a file. You use fs.readFile for that:

fs.readFile('file.txt', 'utf8', fileDataReceived);

We define a callback (a function that is called back after something else) to print the results:

function fileDataReceived(err, txt) {
  if (err) {
    console.error(err);
  } else {
    console.log(txt);
  }
}

Node will start reading the file, then wait for the results in the background while your code continues executing.

When the file read concludes, the callback you passed in (fileDataReceived) will be put on the execution stack.

When your code is fully executed (all called functions exit), Node checks whether there is anything on the execution stack. If there is, it gets invoked.

You can't execute a Fibonacci sequence while doing something else in JavaScript. You can ask another process to execute a Fibonacci sequence while you do something else, which will then notify you when results are available.

Amadan
  • 191,408
  • 23
  • 240
  • 301
1

What you have right now isn't asynchronous, so the execution will block until the recursive(42) call has finished before printing 2. The simplest example of an asynchronous callback I can think of with base JavaScript and Node is something using the setTimeout or setInterval functions.

One way you could do that with your example is like this:

function recursive(n) {
  if(n <= 2) {
    return 1;
  } else {
    return recursive(n - 1) + recursive(n - 2);
  }
};

function callback() {
  console.log(recursive(42))
}

console.log(1);

setTimeout(callback, 0);

console.log(2);

What this will do is

  1. Log 1 to the console
  2. Schedule callback to be called asynchronously after 0ms (so immediately)
  3. Log 2 to the console
  4. Log the result of recursive(42) (which is called by callback) to the console once the function has finished executing
Ananth Rao
  • 1,232
  • 1
  • 9
  • 19