0

Have look on these lines of code

function someAsyncOperation () {
  console.log("inside someAsyncOperation");
  var startCallback = Date.now();
  // do something that will take 10ms...
  while (Date.now() - startCallback <= 100) {
    ; // do nothing
  }
}

someAsyncOperation();

var timeoutScheduled = Date.now();

setImmediate(function () {
  var delay = Date.now() - timeoutScheduled;
  console.log(delay + "ms have passed since I was scheduled");
});


someAsyncOperation();
fs.readFile("./noor.txt",function(err,data){
    var delay = Date.now() - timeoutScheduled;
    console.log(delay + "file read");
});

As I came to know that setImmediate callback is run at the end of the event loop after any I/O operation. But in my case the the setImmediate callback is called before the file read operation returns. Kindly explain why is this happening or what's the logic behind setImmediate callback execution.

nurulnabi
  • 459
  • 3
  • 11

3 Answers3

1

When the program starts execution,

  1. setImmediate will enter in the event loop.
  2. Next, fs.readFile also enters into event loop.

When the program completes execution then it goes into event loop. It checks what I/O callbacks are pending.

  1. Now, fs.readFile comes into picture. But it needs a file to be read. So it keeps a fd(file descriptor) in the OS kernel and says 'Let me know when the file is ready to read' [just for your understanding, it does not really say that line] and comes back without even waiting for 1 nano second.
  2. Now the next setImmediate will start execution.
  3. OS will returns back with fd after opening the file to the fs.readFile in event loop.fs.readFile will be finished now.

So, setImmediate is finished first than fs.readFile

.

Lakshmi Swetha G
  • 2,691
  • 1
  • 9
  • 13
  • As far I know the callback provided in the fs.readFile will not be scheduled in the event callback queue to be executed till the the fs.readFile has successfully/unsuccessfully read the file then only the callback will be scheduled to be executed and since the setImmediate callback has to be called after all callbacks including the I/O (as mentioned in the official documentation) have returned. – nurulnabi Feb 15 '17 at 19:03
  • `fs.readFile(file[, options], callback`) `file` | | filename or file descriptor . `Asynchronously reads the entire contents of a file` : Meaning=> It is queued in loop because there is no other thread to run it parallel in background. Only thing that can be done now is giving the `fd` to kernel. Once this happens it comes back to the loop again but it is already dequeued once, now chance is given to next item in the loop, which in your case is `setImmediate`. When this got called then again the next item in loop starts execution, which is `fs.readFile`. – Lakshmi Swetha G Feb 16 '17 at 05:21
0

Why would you expect fs.readFile() to finish in less than a tick? Especially for fs.readFile() there are multiple operations happening: opening the file, reading one or more chunks, and closing the file. These operations take a fair amount of time (relatively speaking) and can easily take more than one event loop tick before the fs.readFile() callback is called.

mscdex
  • 104,356
  • 15
  • 192
  • 153
  • as I mentioned that the callback scheduled by setImmediate is supposed to run at the end of the event loop what it means that everything has to be finished before the setImmediate callback would be fired this is what the nodejs official documentation tells. Therefore It doesn't matter whatever time is being taken by any piece of code in that particular event loop. – nurulnabi Feb 15 '17 at 18:59
  • The `setImmediate()` callback is executed at the *beginning of the next tick of the event loop* (after I/O callbacks are executed for the current tick of the event loop). However, as I said, it is extremely unlikely that all of the syscalls required to open a file, read the entire file, and close the file would all complete *immediately* such that their callbacks would be executed at the end of the current tick. In fact, I would say it's probably *impossible* due to the async nature (each of the operations are not able to be performed in parallel, so they are performed in series). – mscdex Feb 15 '17 at 22:18
0

setImmediate() function is called in order to stop execution of the currently executing function and to call another function to stop starvation. It is mainly called at I/O operations to stop this functions to eat up the cpu time (implemented at NodeJs asynchronous calls, as it is single threaded). So, it helps a callback function to be executed without any delay.

Whenever setImmediate() is called, it return back to the event loop (also known as uv_loop) in order to execute other queued functions waiting to be executed.

You can also go through this link: setImmediate function

In your code,

Step 1, you are calling someAsyncOperation () which is working synchronously, just printing and waiting for 100ms in the loop.

Step 2, timeoutScheduled assigns the Date.now()

Step 3, again, someAsyncOperation () called which is again doing the same thing (similiar to Step 1)

Step 4, it got one I/O operation i.e. fs.readFile, after encountering this line of code, it goes for setImmediate() function, now delay = Date.now() - timeoutScheduled (delay will hold a value more than 100 for obvious reason, as it waits for 100ms in someAsyncOperation ()

after setImmediate(), it returns to the callback function as no other fd is ready to be executed now. The callback function now prints the appropriate delay value

and the program ends.

Bidisha Pyne
  • 543
  • 2
  • 13
  • _Schedules the "immediate" execution of the callback after I/O events' callbacks and before timers created using setTimeout() and setInterval() are triggered._ this the line I got from the link you given but the behavior of my code is just opposite to it what I mentioned. – nurulnabi Feb 15 '17 at 18:54
  • I have improved the answer according to your code, hope now it helps! – Bidisha Pyne Feb 16 '17 at 06:54