| Asynchronous function chaining in JavaScript |
|
|
|
| Articles Reviews Javascript | |
| Written by James | |
| Tuesday, 30 October 2007 | |
|
For this post, I’m going to be using jQuery, because it’s the closest well-known thing to the library I’m currently working on at my new job. (It’s a wrapper for YUI with lots of syntax niceties.)
Programming asynchronous actions is a pain in the head. Why can’t I do setTimeout($(’#myNode’).hide, 2000)? I need to bind the hide function to the $(’#myNode’) object for starters, and jQuery doesn’t give you a bind method, and besides, binding and execution scope gives lots of JavaScript novices a headache. Wouldn’t this be nice: $('#myNode').wait(2).then.hide(); Over the weekend, I was trying to figure out a general purpose way of adding asynchronous behaviour like this, so I could use it with event handlers, Ajax calls, post-animation callbacks etc. My inspiration came from Methodphitamine (site unavailable, try the Google cache). I won’t bore any non-Rubyists with the details, but the idea is quite simple: create an object with no predefined methods, which accepts any method call and adds the name of the method and its arguments to a queue. This queue can be turned into a function and called on whatever object you want at a later time. Unfortunately, JavaScript has no analogue for Ruby’s method_missing, which means if you want such an object in JavaScript, you need to predefine every method name you might want to use. Big pain. But, you can get something quite usable if you’re implementing an interface (like jQuery’s) that allows chaining. You can pass some object to the constructor for your magical queue-collecting object, and have it implement copies of all the object’s methods. If you need methods from other objects, you can pass those in too. An example, implementing my wait suggestion from above: jQuery.fn.wait = function(time) { var collector = new ChainCollector(this), self = this; // Deal with scoping issues... var fire = function() { collector.fire(self); }; setTimeout(fire, Number(time) * 1000); return collector; }; Powered by jReviews |
|
| Last Updated ( Saturday, 20 September 2008 ) | |
| < Prev | Next > |
|---|







