Search code examples
javascriptarraysmiddleware

javascript call array of functions with the same context


I am trying to create a callback functionality or at least that is how I name it. The main purpose is to call function from an array with the same context and to be able to call the next function in the array from the currently executing function.

This is the code that I have came up with:

function callCallbackChain(context, callbackChain, params) {
    callbackChain.push(function () {
        return true;
    });
    for (var i = 0, len = callbackChain.length - 1; i < len; i++) {
        var cb   = callbackChain[i];
        var next = callbackChain[i + 1];
        if (typeof cb === "function") {
            cb.apply(context, [next].concat(params));
        }
    }
}
var callbackChain = [
    function (next, foo) {
        console.log('1 function call', arguments);
        this.innerHTML = this.innerHTML + "function called + context:" + foo + "<br>";
        next()
    },
    function (next, foo) {
        console.log('2 function call', arguments);
        this.innerHTML = this.innerHTML + "function called + context:" + foo + "<br>";
        next()
    },
    function (next, foo) {
        console.log('3 function call', arguments);
        this.innerHTML = this.innerHTML + "function called + context:" + foo + "<br>";
        next()
    }
];


var d = document.querySelector("#conent");
callCallbackChain(d, callbackChain, ["param from the main function"]);
<div id="conent">
  Initial Content
  
</div>

I can't seem to be able to set next function properly. It is something like a middleware.


Solution

  • Your next function must not actually be the next function in the chain.

    Its the intent to run the next function.

    function run(context, chain, params) {
      var inner_run = (context, chain, params, index) => {
        next = () => inner_run(context, chain, params, index + 1);
        if (index < chain.length) chain[index].apply(context, [next].concat(params));
      };
      inner_run(context, chain, params, 0);
    }
    
    var chain = [
      function (next, foo) {
        this.first = true
        console.log('first', arguments);
        next()
      },
      function (next, foo) {
        this.second = true
        console.log('second', arguments);
        // not calling next()
      },
      function (next, foo) {
        this.third = true
        console.log('third', arguments);
        next()
      }
    ];
    
    var context = {};
    
    run(context, chain, ["param"]);
    
    console.log('context', context);