Understanding Non-Blocking I/O in JavaScript

Published Oct 20, 2017
Understanding Non-Blocking I/O in JavaScript

A piece of data is locked for use by a process — meaning no other process can get access to it. This state may or may not be an interaction with the system disk at any given moment — a blocking operation over Input and Output, blocking "I/O."

But there are various operations (e.g. streams or network operations) that also require this functionality, and they all use threads (computing power).

Blocking methods:
When a thread invokes a read() or write() operation, that thread is blocked until there is some data to read, or the data is fully written.

The thread can do nothing else in the meantime. Some operations, e.g. reading a file, used to be single threaded operations, and the operation had to be completed before another could be executed.

This used to cause bottlenecks, or, like explained in the opening sentence, blocks or deadlocks. This was just how things used to work. There was nothing else until about 2002 for server-side languages.

Non-Blocking Methods:
It is 2009. A miracle occurs: Node.js changes the way front-ends are developed forever. The initial release is supported only by Linux and Mac OSX, and finally, in June 2011, Microsoft and Joyent implement a native Windows version.

Non-Blocking I/O enables a thread to request reading data from a channel, or in the case of front-end technologies from "the Event Loop," gets what is currently available, or nothing at all if no data is available.

Rather than remain blocked until data becomes available for reading, the thread can go on with something else. Revolutionary: speeding up processing time and read/write time quite dramatically, with improved error handling:

// reading a file asynchronously
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;

// reading a file synchronously
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read

So what do threads spend their idle time doing when not blocked in IO calls? Usually performing IO on other channels or on other requests in the event loop.

That is, a single thread can now manage multiple requests of input and output. Blocking methods execute synchronously (at once — the full process from start to finish) and non-blocking methods execute asynchronously — sending and receiving "call-backs" as tokens to and from where their operations are performed.

Discover and read more posts from Theresa Mostert
get started