-
Website
http://osteele.com -
Original page
http://osteele.com/archives/2008/04/minimizing-code-paths-asychronous-code -
Subscribe
All Comments -
Community
-
Top Commenters
-
llimllib
1 comment · 2 points
-
sbecker
1 comment · 1 points
-
mattherdy
1 comment · 1 points
-
ultrasaurus
1 comment · 1 points
-
Facebook User
2 comments · 1 points
-
-
Popular Threads
[blockcode]
requestProductDetails = asyncMemoize(function (id, k) {
ajax.get('/product/'+id, k);
});
[/blockcode]
Here's a definition of asyncMemoize. (My Javascript is rusty, so forgive any bad grammar.)
[blockcode]
function asyncMemoize (f) {
var cache = {};
return function (x, k) {
var v = cache[x];
if (v) {
setTimeout(function() { k(v); }, 1);
}
else {
f(x, function (v) {
cache[x] = v;
k(v);
});
}
}
}
[/blockcode]
(A better definition could use varargs, but whatever.)
I agree that a given function should always or never invoke the callback asynchronously. Not because I want to minimize code paths, but because that's part of the interface. Your first version of requestProductDetails essentially has undefined behavior!
I would go further and suggest a naming convention, either as part of the function name or the name of the continuation argument, that indicates that it's asynchronous. (I've been steeped in Objective-C for the last year, and I'm loving the Smalltalk-style descriptive method/argument naming.)
Making each part of program not rely on the order of execution may seem like a good thing, but it increases the number of required test cases exponentially, if nothing else. Some indeterminacy is inherent in distributed processing; the rest can be determinized.
http://gen5.info/q/category/asynchronous-communications/
// Memoize function
// k must have a signature k(data,id,...);
//Additional arguments are passed to the program.
function asyncMemoize (f) {
var cache = {};
return function (x, k) {
var v = cache[x];
var args = Array.prototype.slice.call(arguments);
args[1] = x;
if (v) {
args[0] = v;
setTimeout(function() { k.apply(null,args); }, 10);
}
else {
f(x, function (v) {
cache[x] = v;
args[0] = v;
k.apply(null,args);
});
}
}
}