Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Design Patterns -- Dealing With Unwanted Asynchrony

I'm pretty new to event-based programming (using node.js). I believe that there's something I'm just not grokking about it, because there's a particular problem that I keep coming across again and again and again.

In short, that problem is dealing with asynchronicity when it seems to be getting in your way. This most often manifests itself, in my case, when working with third-party libraries, which are non-blocking by design and promote a callback-based API.

For instance: Right now I'm writing some stuff that makes heavy use of mranney's node-redis library. My program is scraping RSS feeds and tucking the results into redis. I'm using what I believe is a common strategy with redis:

  1. Scrape feed, store results as a redis hash with a key of something like feed:<feedId>:results:<timestamp>.
  2. Store reference to the latest result under feed:<feedId>:latest.
var redis = require("redis");
var client = redis.createClient();

var get_latest_results = function (feedId) {
    client.get('feed:+ feedId + ':latest', function (err, res) {
        var latest_reading_key = res.toString();
        client.hgetall(latest_reading_key, function (err, res) {
            var latest_reading = res;
        });
    });
    // how do I specify a return value for this function?
}

Placing return latest_reading at the bottom of the get_latest_results function fails, because latest_reading isn't defined until after the function is ready to exit. Placing return latest_reading within the hgetall call fails because the return refers to the callback, and is ignored by get_latest_results.

This is just one example of the kind of situation I seem constantly to write my way into. Maybe I'm trying to pound the square peg into the round hole because I don't know any better. It does seem that there should be a non-hackish way of solving this class of problems.

like image 417
hanksims Avatar asked Oct 12 '10 21:10

hanksims


People also ask

What are different design patterns in JavaScript?

Some examples discussed in the article above include the constructor pattern, the module pattern, the revealing module pattern, the singleton pattern, the observer pattern, the mediator pattern, the prototype pattern, the command pattern, and the facade pattern.

How many JavaScript design patterns are there?

Each pattern has a name and becomes part of a vocabulary when discussing complex design solutions. The 23 Gang of Four (GoF) patterns are generally considered the foundation for all other patterns. They are categorized in three groups: Creational, Structural, and Behavioral (see below for a complete list).


1 Answers

You are struggling with asynchrony because you are still writing your functions in a synchronous paradigm.

In asynchrony you should attach callbacks to events. You shouldn't expect a result from an asynchronous function like get_latest_results(), but you should pass it a callback function as an argument to be invoked when the results are ready. The callback will do whatever needs to be done with your results:

var get_latest_results = function (feedId, readyCallback) {
    client.get('feed:' + feedId + ':latest', function (err, res) {
        var latest_reading_key = res.toString();
        client.hgetall(latest_reading_key, function (err, res) {
            readyCallback(res);                           //--- Trigger Callback
        });
    });
    // how do I specify a return value for this function? //--- You don't
}

Then you can call your function like this:

get_latest_results(1000, function (result) {
   //--- Do whatever needs to be done with the latest result...
});
like image 64
Daniel Vassallo Avatar answered Oct 14 '22 14:10

Daniel Vassallo