0

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.

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.