ware icon indicating copy to clipboard operation
ware copied to clipboard

Middleware should be able to exit the loop

Open stephenmathieson opened this issue 11 years ago • 8 comments

What if we complete our task half-way though the stack?

stephenmathieson avatar Jan 05 '14 20:01 stephenmathieson

hmm whats the use case? im not sure that fits nicely in the middleware abstraction, usually you want the full stack

ianstormtaylor avatar Jan 06 '14 17:01 ianstormtaylor

hmm.. good example would be express:

var express = require('express');

var app = express();

app.use(function (req, res, next) {
  // logic here
  req.foo = {};
  next();
});

app.use(function (req, res) {
  return res.json(req.foo);
});

app.use(function (req, res, next) {
  throw new Error('shouldn\'t get here');
});

app.listen(3006);

stephenmathieson avatar Jan 06 '14 19:01 stephenmathieson

i assume that would be handled by just not calling next? i think this would actually be a reason not to include the magicness of the sync arity functions. but i could be convinced to still add it

ianstormtaylor avatar Jan 06 '14 19:01 ianstormtaylor

i agree the arity stuff does introduce a whole bunch of magic, but i think most people are used to it by now. it's already being used to check if a middleware is an error handler, so not much would have to change.

yeah, i think just not calling next would be the easiest way to handle this.

stephenmathieson avatar Jan 06 '14 19:01 stephenmathieson

yeah, agreed -- just not calling next seems like a good way to go to me.

calvinfo avatar Jan 07 '14 22:01 calvinfo

I know this is super old now, but the ability to be able to call done is incredibly useful but likely outside the scope of the module. In personal projects of mine, I've utilised a middleware-esque stack (in reverse since that was simpler) in a similar fashion on the UI. Everything runs through middleware until a member can handle it and call done. A couple of examples:

  • Ajax request chain - the base xhr is registered with the ability for other middleware to modify the request before it gets there (add a proxy, alter data, etc.)
  • UIs - hitting a keyboard button will send the key combination through middleware and when multiple menus/modals/etc. are open it'll close the last registered instead of them all (each registered callback unregisters itself)
  • Persistence - you can register both pass through persistence (a cache) and/or override it completely by registering before the default persistence method

Express and friends don't need this sort of thing because the response is technically the done callback. There is no need for registering a callback after this occurs but it is possible to do using res.on('end'). All of these require a callback at the end to know when the stack is done running, which isn't possible when you omit next. Is this a pattern somewhere else already?

blakeembrey avatar Aug 29 '14 20:08 blakeembrey

Though not ideal, you could call fn(new Error('done')) to jump down to the bottom.

matthewmueller avatar Sep 03 '14 09:09 matthewmueller

FWIW, since the synchronous support update, it's actually difficult to now stop the flow anywhere along the chain making it unusable for middleware flows in something like express.

blakeembrey avatar Sep 26 '14 17:09 blakeembrey