It’s not uncommon to be in the need to call an async function at an interval in order to get some data from a remote URL, or for instance, checking the status of a service.

I’ve used a couple of npm modules that interface with a REST API (like i.e. node-twitter or node-flickr) and sometimes I want to keep my code updated about an API endpoint data update…

… For accomplishing this, I usually poll that endpoint on an interval making a request and comparing the last response with the new one in order to get updated on changes.

I will call poll to every iteration done on a fixed interval by a function.

Creating a polling function

Let’s assume that for some reason, I want to check the latest commits on the Kernel’s public repo using the Github API…

I can write something like this:

var request = require("request"),
url = "https://api.github.com/repos/torvalds/linux/commits";function mypoll() {
request.get(url, function mycallback(err, req, data) {
if (err) {
console.log(err);
}
console.log(data);
});
}

Emitting an event when the poll ends

What about if I want an evented interface to notify me about successful pollings? Or even notify me when the polled data differs from time to time?

I wrote a module called polling-to-event that may come in handy for a task like that (See the full docs for polling-to-event).

var request = require("request"),
pollingtoevent = require("polling-to-event");var url = "https://api.github.com/repos/torvalds/linux/commits";var emitter = pollingtoevent(function(done) {
request.get(url, function(err, req, data) {
done(err, data);
});
});
// Then I have a nice EventEmitter interface for the pollings.
emitter.on("poll", function(data) {
console.log(data);
});emitter.on("error", function(error) {
console.log("poll failed with error: %s", error);
});

Now I have an event emitter that will emit a poll event at an interval, and when the data arrives for each poll. All I have to do is to:

  • Create a function that accomplishes the task of requesting the data.
  • Create the emitter with polling-to-event.
  • Call done(null, data) inside my function’s when the async code is done and pass it the polled data. (done() is a standard error first callback. I pass it null as first parameter if nothing bad happened, or an Error if I want the emitter to emit the standard ‘error’ event for NodeJS code).

Getting an event only when the polled data changed from a previous poll

This action of polling and only being warned when the polled data changes is sometimes called long polling.

pollint-to-event will emit a longpolling event when the previous poll and the current one differ.

The comparison wil only be done (and the longpolling event emitted) if I pass an option longpolling:true to the emitter creation.

This is optional in order to avoid recurrent comparison when I’m not interested in diffs and I’m polling big chunks of data.

var emitter = pollingtoevent(function(done) {
request.get(url, function(err, req, data) {
done(err, data);
});
}, {
longpolling:true
});
emitter.on("longpolling", function(data) {
console.log("New data arrived: %s", data);
});

And then I have an evented interface for my pollings.

The event emitted returned by polling-to-event will notify me with an event every time the polling function finishes its job and also when the polled data differs from last pollings.