In business, we often encounter the situation of if-else multi-branch use and nested use. Once the business logic is complex, the code becomes difficult to maintain, and errors will be reported if a few words are changed casually. The eyes need to see flowers, and the use of strategy mode feels that the universality is not too strong Therefore, I wrote an If() function in the exploration, which can greatly improve the code maintenance problems caused by if-else

The following will introduce the use of the If() function in some business scenarios, and see If it can help solve the common pain points of if-else

Let’s start with the basics to avoid confusion:

  If() // Generate an If instantiated object
 const newIf=If() / / solid column
// Other interfaces:
 newIf.of() // Call the of method to store the condition
 newIf.fn() // call fn to store the function body
 newIf.then() // Call the then method to check the condition and execute
Copy the code

So what’s If()?

Such as:

/ / 1
if(value===1){
   pass()  
}else{
   error()
}

// Using the If function is equivalent to:
If(1= = =1).then(pass,error)

// Or use chain calls
If(1= = =1).then(pass).then(error)

/ / 2
if(value===1){
pass()
}else if(value===2){
error()
}

// This is equivalent to:
If(value===1,value===2).then(pass,error) 
If(value===1,value===2).then(pass).then(error)
Copy the code

The If() function is a functional programming approach to if-else multi-branching

I won’t go into the details of the principle, because the principle is fairly simple: add all branches to an execution queue, and basically propagate a solution to a problem
If is already very simple, what good is it to use it this way?

Consider a simple business scenario that shows or hides a button and does a series of business operations via Boolean state, typically written this way

if(value===true){
  show()
  other()
}else{
  hide()
}
Copy the code

Then the business requirements changed. Display this button regardless of Boolean, but do other business operations

if(value===true){
  show()
  other()
}else{
  //hide()
}

// Now the code structure is a little bit ugly
value===true? show(),other():nullThe downside of this is that it's simpler to change the structure, but it's a hassle to change it back in case the function needs to be returnedCopy the code

Now I can do this

# 1 the If (value = = = true). Then (= > show () (), other ()) / /. Then (() = > hide ()), one thousand which day product convulsions directly to come home, structure is good tooCopy the code
Demonstration 2 Multi-branch use:
. other1()// Various business codes
if(value===1){

}else if(value===2){

}else if(value===3){

}else if(value===4){

}else if(value===5){

}else if(value===6){

}

other2()
...
Copy the code

Can do logic checks and function body separation

# 2 * * * * * * block / / * * / / array logic check data format const condition = [value = = = 1, value = = = 2, value = = = 3, value = = = 4, value = = = 5, value = = = 6, Const condition={check1:value===1, check2:value=== =1,} action2:()=>{log(2)}, ........ }Copy the code

After modification using the If() function

. other1()// All sorts of messy business code

 // The execution phase is abstracted into a line of code
If(condition).then(action) // value=3
other2()
...
Copy the code

The benefits of this are obvious. Abstract data can be reused if it depends on multiple state codes

The business code is separated from the complex branch structure, making the code easier to maintain and the structure more beautiful and clear

You can optimize it, but let’s look at the basic usage

Interface introduction once:

 If() // Generate an If instantiated object
 const newIf=If() / / solid column
// Other interfaces:Newif.fn () stores the function body newif.then () checks the condition and executesCopy the code
Basic usage:

The If () column

// The parameter store type is Boolean and can accept arrays or objects or functions
If(arg[type:boolean,array,object,function])  

If(value===1)
If([value===1,value===2]) 
If({check1:value===1,check2:value===2}) // Use objects as parameters for complex branching scenariosIf([() = >{})// The function needs to return a Boolean value
Copy the code

Then method

// Then arguments are stored in the function body type array, object, function, function body can accept arguments,
If().then(arg[type:function.array.object])  
then([fn1,fn2])
then({fn1:fn1})
then(fn1)
Copy the code

The relationship between the body of a function and a Boolean value is one – to – one mapping

const condition=[value===1,value===2,value===3]
const action=[(a)= >{},()=>{},()=>{}]
If(condition).then(action) 
// condition[0] executes action[0], and so on
Copy the code

Obscure things to see how to optimize

If the business logic is simple enough, it can be changed to the body of the loop

The ultimate link

# 3 / / the above code into a const newIf = the If () [6]. ForEach ((the value index) = > newIf) of (value = = = index), fn (() = > log (index))) Newif.fn (); newif.fn (); newif.fn (); newif.fn (); newif.fn (); newif.fn (); newif.fn ()Copy the code

#1, #2, #3

Advanced use:

Example 3 Solution -> Nested multiple branches:

#1
if(){
  if(){
    if(){
       if(){
        if(){
          if(){
    }    
    }  
    } 
    }
  }
}
Copy the code

Use the If function to modify

#2 const newIf=If() newIf.of(value===1) .then(()=>newIf.of(value===2) .then(()=>newIf.of(value===3)) .then(()=>newIf.of(value===4) .then(()=>newIf.of(value===5) .then(...) ))))Copy the code

Recommendation:

# 3... action5=()=>newIf.of(value==4).then(action7) action4=()=>newIf.of(value==4).then(action6) action3=()=>newIf.of(value==4).then(action5) action3=()=>newIf.of(value==4).then(action4) action2=()=>newIf.of(value==3).then(action3) action1=()=>newIf.of(value==2).then(action2) newIf.of(value===1).then(action1)Copy the code

Simple business logic can also be optimized in cycles:

# 4 const arr = [6]. The map ((item, index) = > () = > newIf) of (value = = = index). Then (arr) [index + 1]}) newIf.of(v===1).then(arr[0])Copy the code

#1, #2, #3, #4 is equivalent

Delayed use:

const newIf=If(value===1).fn((a)= >{log(1)})
setTimeOut(newIf.then()) / / output 1

Copy the code

Separated from function body:

const newIf=If()
newIf.of(value===1).fn((a)= >log(1))
newIf.then() / / output 1
Copy the code
The condition as a function body uses + to pass arguments
If((a)= >{
  return {
    boolean:true.// To be used as a function, you must return an object with a Boolean value
    value,
    age,
    name,
    ....
  }
}).then(({value,age,name}) = >{
  log(value,age,name)
}) 
Copy the code

Use the advanced

Jump out of infinite recursion with parameter passing:

Sometimes we send a piece of information based on the state of a piece of data, wait s seconds and then add another piece of information


let isTips=value===true 
if(isTips){
  sendMessage('1')
  setTimeout((a)= >{
    if(isTips){ 
      setTimeout((a)= >{
      if(isTips){
            sendMessage('3')
                setTimeout((a)= >{
                if(isTips){
                      sendMessage('4')}})}},2000)}// The value after x seconds is uncertain

       sendMessage('2')},1000)}Copy the code

Now let’s do that

const isTips=(a)= >{
  
  return {
     boolean:value===3.message:message,
     delay:delay
  }
}
const send=({message,delay}) = >{
   sendMessage(message)
   return delay
}

setTimeout((a)= >{
res=If(isTips).then(send).result()   // res equals the return value of send

},1000)
Copy the code

Tandem use – Random extension of functionality

Sometimes, maybe requirements are constantly being added and removed. How do I change that?

function run(){
  action1()
  action2()
  action3()
  //action4()
}

if(value===true){
    run()
}


Copy the code

The If function looks like this

If(isTips)
.then((a)= >log(1))   / / output 1
.then((a)= >log(2))  2 / / output
.then((a)= >log(3)) 3 / / output
//.then(()=>log(4)) depends on the last conditional output as long as true is continuously executed then body

Copy the code

Chain call:

If(value===3).then((a)= >log(...) ) .of(value===3).then((a)= >log(...) ) .of(value===4).then((a)= >log(...) ) .of(value===5).then((a)= >log(...) )Copy the code

Asynchrony uses + parameter passing + delay checking + reuse

const newIf=If()

let value=0
newIf.of((a)= > {
  
  return {
    boolean: value===3  
    value:value,
    state: value===3? Pass: not pass text:'... '. } } ) setTimeout((a)= >{
value=3},2000)

setTimeout( (a)= >{
  newIf.then(({value,state,... }) = >{
    log(value,state) // value=0,state= no pass})},1000)

setTimeout( (a)= >{
  newIf.then(({value,state,... }) = >{
    log(value,state) // value=3 state= Pass})},5000)

Copy the code

If function features:

If-else branch can be used for nested if-else branches. Optimized code structure. 4. Support chain call 5. Support basic if-else structure 6. Support asynchronous call 7. Support condition and function body separation

npm i ya-if