简体   繁体   中英

How to compile multiple functions into function chain in Javascript?

I want to be able to provide compile a function (for a web framework I'm working on) into a "function chain" as seen in most web frameworks. What is the easiest way to do this? Let's say I have a list of functions:

const middleware = [
function(data, next){
    console.log(data); 
    next()
},
function(data, next) {
   return;
}, function(data, next) { }];

In the above case, the ideal behaviour would be for the first function to trigger, the passed in parameter next to trigger the next function and then the chain to end due to the return statement. How could I compile this to one function?

不是 100%,但我相信如果你在第一个函数之后为完成的产品创建一个变量,你可以将第二个函数应用于它并将它从第一个函数传递给第二个函数

You can simply reduce the array of functions:

functionList.reduce((output, fn) => fn(output), undefined);

That will run them in order, passing the result of the previous call as a parameter to the next call, ultimately ending with the final result from the last function call.

As an example, if you do that with this as your functionList:

[
  () => 4,
  n => n+5,
  n => `$${n}`,
  amt => amt + '.00'
]

The result will be $9.00

Ok, I've found an answer - you can use the following code, which I adapted from koa-compose. To compile the middleware chain you can use the following function:

function compiler(middleware) {
  // return function to execute compiled middleware chain
  return function(data, next) {
    // set pointer to 0 to match middleware index to track if next()
    // is called twice in one middleware
    let pointer = 0;
    function dispatch(i) {
      // check if pointer is larger than i, indicating next() was called more than once
      if (i < pointer)
        return Promise.reject(
          new Error("next() called multiple times in one middleware function.")
        );
      // set pointer to next index
      pointer = i + 1;
      // grab current function
      let fn = middleware[i];
      // if out of middleware, assign the next function from the parameters to be executed next
      if (i === middleware.length) fn = next;
      // if no function (out of middleware and no provided parameter), end middleware execution
      if (!fn) return Promise.resolve();
      try {
        // run next function, binding the second parameter to the next middleware in the chain
        return Promise.resolve(fn(data, dispatch.bind(null, i + 1)));
      } catch (err) {
        return Promise.reject(err);
      }
    }
    // start function on first middleware
    return dispatch(0);
  };
};

You can compile the middleware functions and execute it like the following:

const funcs = [
     function(data, next){
          console.log(data); next();
     }, function(data, next){
        console.log('done');
     }];
const compiled = compiler(funcs);

// execute compiled middleware chain
compiled();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM