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:
feed:<feedId>:results:<timestamp>
.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.
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.
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).
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...
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With