Reputation: 13344
I'm working on a function pipeline somewhat similar to Connect/Express request pipeline with use()..
A request handler runs through a stack of functions that were added using a .use() function. Async, as a n() function must be called to continue.
The functions are called using the familiar (req, res, next). This works, but its last added first executed, which I'm finding confusing and I'd like to make it first added first executed. This works for last in and continues the r, s references across the pipeline..
(I use r, s instead of req, res in these examples..)
var s = {
chain: function(r, s, n){
// this runs last, was first added
s.end();
},
use: function (f){
this.chain = (function(nxt){
return function(r, s, n){
f(r, s, nxt.bind(this, r, s));
}
})(this.chain);
},
listen: function (){
this.use(function (r, s, n){
// this runs first, was last added
n();
})
var svr = require('http').createServer(this.chain);
svr.listen.apply(svr, [].slice.call(arguments)); // accept same args
}
}
s.use(function(r,s,n){...});
s.use(function(r,s,n){...});
s.listen(8080);
Here's an attempt at FIFO. But it doesn't work. Ideas?
var chain = function(r, s, n){
console.log(1, arguments);
n();
};
function use(f){
var th = chain;
chain = (function(nxt){
return function(r, s){
th(r, s, nxt);
}
})(f);
}
use(function(r, s, n){
console.log(2, arguments)
n();
})
use(function(r, s, n){
console.log(3, arguments)
n();
})
chain(0,1);
Would like something that doesn't use loops to run thru the functions.
Upvotes: 0
Views: 483
Reputation: 50807
I don't exactly what it is you're trying to duplicate, but would this fiddle serve as a good starting point?
var chain = function(fn) {
var queue = fn ? [fn] : [], index = 0, req, res;
var run = function(r, s) {
req = req || r; res = res || s;
if (index < queue.length) {
queue[index++](req, res, run);
}
};
return {
use: function(fn) {
queue.push(fn);
},
run: run
};
};
var c = chain();
c.use(function(r, s, n) {log(r, s, 1); n();});
c.use(function(r, s, n) {log(r, s, 2); n();});
c.use(function(r, s, n) {log(r, s, 3); n();});
c.use(function(r, s, n) {log(r, s, 4); n();});
c.run("req", "res");
//=> req, res, 1
// req, res, 2
// req, res, 3
// req, res, 4
You could also supply a function in the initial call to chain
if you preferred.
Upvotes: 2