Async/Await & Generator Middleware Composition

2.3.0 · active · verified Wed Apr 22

The `composition` package provides a utility for composing asynchronous middleware functions in a manner similar to Koa. It uniquely supports mixing both traditional generator functions (using `yield next`) and modern `async/await` functions within the same middleware stack. Each composed middleware function is expected to return a Promise or handle `next()` correctly to ensure the control flow propagates. The package is currently at version 2.3.0, indicating a stable release focused on robust async control flow. While no explicit release cadence is documented, utilities of this nature tend to be stable with updates driven by significant changes in JavaScript's asynchronous patterns or bug fixes. Its key differentiator is the seamless interoperability between generator-based and promise-based async middleware, making it suitable for projects transitioning or requiring compatibility across different asynchronous programming styles.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to compose a stack of mixed generator, promise-returning, and async/await middleware functions, illustrating the control flow, context passing, and handling of return values and errors.

var compose = require('composition');

var stack = [];

// Middleware 1: A generator function
stack.push(function* (next) {
  console.log('Middleware 1 (generator): Before calling next()');
  yield next;
  console.log('Middleware 1 (generator): After next() returned');
});

// Middleware 2: A regular function returning a Promise
stack.push(function (next) {
  console.log('Middleware 2 (promise): Before calling next()');
  return Promise.resolve('Data from Middleware 2').then((data) => {
    console.log('Middleware 2 (promise): Received data:', data);
    return next(); // Ensure next is called and its result is returned as a Promise
  }).then(() => {
    console.log('Middleware 2 (promise): After next() returned');
    return 'Modified by Middleware 2';
  });
});

// Middleware 3: An async/await function
stack.push(async function (next) {
  console.log('Middleware 3 (async/await): Before calling next()');
  const result = await next(); // Await the result of the downstream middleware
  console.log('Middleware 3 (async/await): After next() returned with:', result);
  return 'Final value from Middleware 3';
});

// Compose the middleware stack into a single function
var fn = compose(stack);

// Invoke the composed function, which returns a Promise
fn.call({ customContext: 'hello' }).then(function (finalVal) {
  console.log('Composed function resolved with final value:', finalVal);
}).catch(function (err) {
  console.error('Composed function caught an error:', err.stack);
  process.exit(1);
});

view raw JSON →