I wrote an awesome node.js module for use at StackVM - a module called node-lazy that does lazy list processing through events!

It comes really handy when you need to treat a stream of events like a list. The best use case currently is returning a lazy list from an asynchronous function, and having data pumped into it via events. In asynchronous programming you can't just return a regular list because you don't yet have data for it. The usual solution so far has been to provide a callback that gets called when the data is available. But doing it this way you lose the power of chaining functions and creating pipes, which leads to not that nice interfaces. (See the 2nd example below to see how it improved the interface in one of my modules.)

Check out this toy example:

var Lazy = require('lazy');

var lazy = new Lazy;
lazy
  .filter(function (item) {
    return item % 2 == 0
  })
  .take(5)
  .map(function (item) {
    return item*2;
  })
  .join(function (xs) {
    console.log(xs);
  });

This code says that lazy is going to be a lazy list that filters even numbers, takes first five of them, then multiplies all of them by 2, and then calls the join function (think of join as in threads) on the final list.

And now you can emit data events with data in them at some point later,

[0,1,2,3,4,5,6,7,8,9,10].forEach(function (x) {
  lazy.emit('data', x);
});

The output will be produced by the join function, which will output the expected [0, 4, 8, 12, 16].

And here is a real-world example. Some time ago I wrote a hash database for node.js called node-supermarket (think of key-value store except greater). Now it had a similar interface as a list, you could .forEach on the stored elements, .filter them, etc. But being asynchronous in nature it lead to the following code, littered with callbacks and temporary lists:

var Store = require('supermarket');

var db = new Store({ filename : 'users.db', json : true });

var users_over_20 = [];
db.filter(
  function (user, meta) {
    // predicate function
    return meta.age > 20;
  },
  function (err, user, meta) {
    // function that gets executed when predicate is true
    if (users_over_20.length < 5)
      users_over_20.push(meta);
  },
  function () {
    // done function, called when all records have been filtered

    // now do something with users_over_20
  }
)

This code selects first five users who are over 20 years old and stores them in users_over_20.

But now we changed the node-supermarket interface to return lazy lists, and the code became:

var Store = require('supermarket');

var db = new Store({ filename : 'users.db', json : true });

db.filter(function (user, meta) {
    return meta.age > 20;
  })
  .take(5)
  .join(function (xs) {
    // xs contains the first 5 users who are over 20!
  });

This is so much nicer!

If you wish to try node-lazy just do npm install lazy! Alternatively, if you don't have npm, you can git clone http://github.com/pkrumins/node-lazy.git and set your NODE_PATH environment variable to point to that directory.

Enjoy and follow the future node-lazy developments in its github repo - node-lazy at github!

Article Sponsors

None!

Want to sponsor my future (or past) articles? Contact me for prices and options!

Comments

October 14, 2010, 00:53

Another neat thing about this module is that Lazy() can take an EventEmitter as an argument and custom event names, so you can wrap a Lazy() chain around existing streaming interfaces pretty easily.

Matt Freeman Permalink
October 14, 2010, 05:52

Does reactive extensions do same thing I believe?

October 14, 2010, 14:04

They have similar interface.

October 27, 2010, 08:35

Interesting take on asynchronous lists :)

November 01, 2010, 01:49

Nice, that goes hand in hand with Redis. Great package !

Nisar Permalink
January 30, 2014, 09:06

Sir I try to run first example lazy module after installing there are error become
1:invalid REPL keyword;
2:xs is not define

Hodges Permalink
March 10, 2014, 20:16

What a great analysis and see this here helpful for education point of view.

March 12, 2014, 06:15

Wonderful tips. It is useful for me,thanks a lot for giving everyone an exceptionally splendid possiblity to read in detail from this blog. I will bookmark your blog and check again here frequently.

Riosas Permalink
March 17, 2014, 08:21

Java script one the greatest script in the world and http://www.essaypenguins.com/write-my-essay this is helpful online.

Leave a new comment

(why do I need your e-mail?)

(Your twitter name, if you have one. (I'm @pkrumins, btw.))

Type the first letter of your name: (just to make sure you're a human)

Please preview the comment before submitting to make sure it's OK.

Advertisements