JS example of chain of responsibility pattern

In everyday situations where parameters/business logic/state and so on need to be prechecked or interrupted, this kind of streaming and interruptible code is better suited to the chain of responsibility pattern. This problem is solved by designing a chain structure.

Design structure

  • The target task

The final task to be performed

  • Adding interceptors

Other processing tasks in the process, such as precheck, etc

  • Start task

Execution starts with the first interceptor

  • Continue or interrupt the task

Interceptor to determine whether to proceed to the next step

JS code implementation

class TaskChain {
  //target: target task
  constructor(target) {
    this.target = target
    this.index = 0              // Interceptors execute subscripts
    this.interceptorSize = 0    // Number of interceptors
    this.interceptors = []      // Interceptor collection
  }
  // Add interceptor
  //interceptor: function(TaskChain) {}
  // Call taskchain-.process () to continue the task
  addInterceptor(interceptor) {
    this.interceptors.push(interceptor)
    this.interceptorSize++
    return this
  }
  // Execute the task
  process() {
    // Initialize the subscript
    this.index = 0
    this.next()
  }
  // Continue execution
  next() {
    if (this.index < this.interceptorSize) {
      // Get the interceptor of the current subscript, and then incrementing the subscript to get the next interceptor
      this.interceptors[this.index++](this)
      return
    }
    if (this.target) {
      // Execute the target task
      this.target()
    }
  }
}
Copy the code

Using the example

Several interception tasks can be simulated at will, intermediate process can be added at will, asynchronous intermediate process can be added, so that the code is better to maintain, better to read

// Simulate several interception missions at will
function signin() {
  let name = "xiaobai"
  let password = "123"
  new TaskChain(() = > {
    // Target task
    console.log("Successful landing.")
  }).addInterceptor((task) = > {
    // Precheck for null
    if(! name || ! password) {console.log("Account password cannot be empty.")
      return
    }
    // Precheck succeeded, next step
    task.next()
  }).addInterceptor((task) = > {
    // Whether an account exists
    if(name ! = ="xiaobai") {
      console.log("Account does not exist")
      return
    }
    // Precheck succeeded, next step
    task.next()
  }).addInterceptor((task) = > {
    // Check whether the password is correct
    if(password ! = ="123") {
      console.log("Password error")
      return
    }
    // Precheck succeeded, next step
    task.next()
  }).process() // Start the task
}
Copy the code