Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement blocking control flow in NodeJS

I am trying to create a blocking control flow, but have hit a dead end. The idea is that a request comes in and flows through a number of handler functions. Each function does something and decides whether or not the request is now fulfilled. If it is, the handling stops, if not, the next handler is invoked. Each handler might or might not do something asynchronously (like fetching/writing data). If that is the case, then the following handlers depend on the data being there before being started.

So far, I have two ideas, which both do not quite match these requirements: 1) All handlers are functions, which are pushed into an array and iterated over with some . If a handler wishes to stop the control flow, it simply needs to return true. With this approach, I can't have any of the handlers invoking asynchronous functions.

2) All handlers are promises which are chained. This seems like a better idea to me, but I can't figure out how to best handle stopping the control flow. I have two ideas: - Keep a variable which is set to true once a handler decides to interrupt the flow. Check this value in every single handler and resolve immediately, if needed. This means a lot of duplicate code. - Rejecting a promise if it does not wish to continue the normal flow, and continuing in catch. However, the thought of using errors as a means of controlling the flow pains me - and also it means that I have to handle the case where the catch is invoked because of an actual error.

My spidey senses tell me there has to be another way, but I can't figure it out.

like image 954
Philipp Avatar asked Jan 25 '26 09:01

Philipp


1 Answers

You can use ES6 generators to generate the promises as needed. Each time a promise resolves it could check for a stop value and if false (i.e. continue to the next handler) ask for the next from the iterator.

function* promiseHandlers() {
  const handlers = [
    promiseHandler1,
    promiseHandler2,
    promiseHandler3,
    promiseHandler4,
    promiseHandler5
  ];

  for (const handler of handlers) {
    yield handler();
  }
}

function run(iter) {
  const i = iter.next();
  if (i.done) {
    return Promise.reject(new Error("end of iterator reached"));
  }
  return Promise.resolve(i.value).then(result => result || run(iter));
}

run(promiseHandlers());

This isn't actually chaining though. Instead it would execute each promiseHandler in order but the results of those are not passed to the next. I think this is correct for what the OP wanted especially since a truthy result ends the iteration (i.e. break).

like image 192
Sukima Avatar answered Jan 26 '26 21:01

Sukima



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!