/ JavaScript

Functional Asynchronous Programming in node.js

Using callbacks is the node.js way to return the value of the asynchronous operations[1]. Callback is a function receiving two arguments: error and result.

// callback for the file reading operation
var print = (err, data) => console.log(data);

require('fs').readFile('text.txt', {encoding:'utf8'}, print);

The callback function type is error -> mixed -> (), where error is the error type and mixed denotes value of any JS type (object, string, number, etc).

Let's create the function value that converts the given value to function with one callback argument:

var value = v => cb => cb(null, v);

Its typedef is mixed -> ((error -> mixed -> ()) -> ()). The function receives some value and returns function that receives callback and immediately runs it, providing the given value as its result.

This function makes calls to asynchronous functions replaceable with values without affecting the control flow.

value('ok', print);

Now construct the read and write functions that receive and return values:

var read = filepath =>
  callback =>
    filepath((_, filepath) => 
      fs.readFile(
        filepath,
        { encoding : 'utf8' },
        callback));

var write = (filepath, data) =>
  callback =>
    filepath((_, filepath) =>
      data((_, data) =>
        fs.writeFile(filepath, data, callback)));

The error handling is skipped to keep the code simple.

It is now possible to read one file and save its content to another by calling asynchronous read and write similarly to their synchronous counterparts:

write(value('file.out'), read(value('file.in'))();

The trailing () is not a mistake - it invokes write.

Constructing a library of async functions wrapped following this pattern makes possible to write code using these functions like if there are synchronous:

var tokens = readTokensFromDb(value('user'));
var html = replaceTokens(read(value('template.html')), tokens);
sendEmail(html)();

where readTokensFromDb, read, replaceTokens, sendEmail are asynchronous.


  1. Node.js style callbacks, https://nodejs.org/api/errors.html#errors_node_js_style_callbacks ↩︎

Alex Netkachov

Alex Netkachov

Alex works at Central London on the next generation of energy trading solutions to traders, brokers and exchanges worldwide.

Read More

Why not to stay updated if the subject is interesting? Join Telegram channel Alex@Net or follow alex_at_net on Twitter. Or just, use the comments form below.