We often hear people say that only writing business can not improve, business code can meet the requirements, etc., in the long run, we will be exhausted by the complex requirements, no time to learn, stay for a period of time feel that there is no improvement in another business. This vicious cycle is bad for our own careers.

So, knowing that this is going to happen, what we need to do is to avoid it. Through the code to exercise our thinking ability, improve themselves in the work, when the time is up, naturally into the factory, the salary doubled!

But this post isn’t going to teach you how to do that, it’s just going to share my thoughts when I write a business, and how MIDDLEWARE came to me from the if else.

demand

There is a need:

Batch open a function, the back end will do a check when open, the unsuccessful list thrown out, the front end to do the display, the check will have two cases, so an interface returned two fields, and these two fields are not necessarily returned. The following situations:

  • Both A and B
  • A has B has no
  • B has no A
  • Neither A nor B

The desired effect of the interaction is this:

  • Both A and B have pop-ups: pop up A first, click OK and then pop up B, close B and prompt completion
  • A has B no: play A pop-up window, closed after the prompt is completed
  • B has A no: play B pop-up window, closed after the prompt is completed
  • A, B: prompt complete

So you can think about what would happen if you had a requirement like that, and the normal way to think about it is if, right

  • If there are two conditions, first show the first, click close and then show the second, close the second and show the prompt
  • If there is only one condition, display the popover under the specified condition, and display the prompt when closed
  • If there is no condition, do not show the popover, show the prompt directly

Demo

const { A = [], B = [] } = res.result;

if (A.length > 0 && B.length > 0) {
  Modal1.info({
    onOk: () = > {
      Modal2.info({
        onOk: () = > message.success('tip')})}});return;
}

if (A.length > 0) {
  Modal1.info({
    onOk: () = > message.success('tip')});return;
}

if (B.length > 0) {
    Modal2.info({
    onOk: () = > message.success('tip')});return;
}

message.success('tip');
Copy the code

This Demo is a little bit simplified, just to show you the general logic, but actually popovers are a lot more complicated than that.

thinking

As you can see, this code is very redundant, with a lot of duplicate code, and you accidentally miss which logic or bug can result. As an engineer, we should solve the problem with the idea of engineering. If we write too much, we will feel that this code is boring. If we want to add some other logic in the future, we must move to the current code. One of my rules for writing code is to keep the previous code as little or as little as possible, so there will be fewer bugs, so compatibility and reusability should be taken into account when writing code.

Ok,, since there is no need to satisfy the redundant if else and a large number of duplicate code, we need to solve it, so we began to work overtime to find a solution.

Promise

The original idea was to use Promise to solve the problem, because Promise has an all method that can set the state of Promise to resolved when the popover closes. Promise. All ([p1, p2]) can get all popover opening and closing states. When all popovers close, it will tell you that it is done.

However, there is another problem that cannot be solved, that is, the problem of sequential display. Although the tasks in the Promise container are asynchronous, the execution of the Promise is synchronous, and the pop-ups will appear together. Take a look at the Demo below

Demo

const { A = [], B = [] } = res.result;
const promises = [];

if (A.length > 0) {
  const p1 = new Promise((resolve) = > {
    Modal1.info({
      onOk: () = > resolve()
    });
  })
  promises.push(p1);
}

if (B.length > 0) {
  const p2 = new Promise((resolve) = > {
    Modal2.info({
      onOk: () = > resolve()
    });
  })
  promises.push(p2);
}

Promise.all(promises).then(() = > {
  message.success('tip');
})
Copy the code

Can see here have resolved the popup window at the end of the tip, and does not require much logic, the logic of each pop-up independent, each other, even if later add Windows and logic, and basically does not affect the business before, so business logic isolation and independent here basically achieved, but can not achieve, one of the most important function is, in turn, play the window display, Close the previous one before displaying the next one.

This Demo is no matter how many popovers you have, as long as you show them, all of them will be displayed. No way, continue to work overtime ~

The middleware

In recent years, middleware has been used more and more frequently in front end tools, libraries and frameworks from Express to Koa to Redux.

Here is a brief description of the middleware used in Express. Express is a Node framework that helps you quickly build a Web server. App. use in Express is what we call using middleware. So what exactly is middleware?

When we send a request from the browser, we need to perform a series of processing and parsing in the server to get the data we want. This series of processing is the task of the middleware, for example:

  • To obtaingetData in the request body
  • To obtainpostData in the request body
  • Parsing the Cookie
  • Parsing the Session
  • .

This can be done by middleware so that we can focus on the business.

app.use(function (req, res, next) {
  / /...
  // If the next middleware is not called, the execution will not proceed
  // Next () is used to call the next matching middleware
  next();
})
Copy the code

Well, with a bit of prior knowledge it’s time to move on to our business. Knowing what middleware does, you need to do something with it.

The function we want to implement is actually task processing mechanism: the latter task needs to wait until the previous one is finished, and the existence of the former task is uncertain, so it is good to implement it.

Demo

const { A = [], B = [] } = res.result;
const taskQueue = [];

if (A.length > 0) {
  // Create a subtask and add it to the task queue
  // When finished, call next to start the next task
  const subtask = (next) = > {
    Modal1.info({
      onOk: () = > next()
    });
  }
  taskQueue.push(subtask);
}

if (B.length > 0) {
  const subtask = (next) = > {
    Modal2.info({
      onOk: () = > next()
    });
  }
  taskQueue.push(subtask);
}

// This is the core code
const next = () = > {
  // Pops up the first task in the task queue
  const subtask = taskQueue.shift();
  
  // Execute it if it exists and pass it to next
  // If the task queue does not exist, the task queue is empty, which triggers the end event
  if (subtask) {
    subtask(next);
  } else {
    message.success('tip');
  }
}

next();
Copy the code

The Webpack loader does much the same thing, with a specific loader handling files. Then the processed result is passed to the next loader, which is essentially task processing.

start => subtask1 => subtask2 => ... => end

In fact, the implementation here is just a simple section, we usually can learn more about the well-known library and framework of the source code, there are a lot of things worth learning. See more have some natural know, and now a lot of front-end concepts are moved to the back end, have time to understand the back end things, will be very helpful to our career, maybe one day you put the back end concept moved to the front end, that you are the industry leader! 🤪

conclusion

Actually in our daily work has a lot of code can be optimized, only on demand, in a hurry, a lot of places is to achieve a business line, optimization is always left to the next, so in peacetime still to be strict with themselves, not just satisfied with business implementation, many think of reusability, extensibility and high performance, time grew, the level of the code have naturally brought!