JavaScript Pipeline
Tags: javascript, pipeline, webdev, programming
Published: 2023-07-13 11:07:24

## INTRO
`Pipeline` is the beautiful concept in javascript contains functional chaining.  That means one function returned value passed as argument to another function. It is repeated process until we get required result.

Currently ECMASCRIPT working on pipeline  operator ( |> ) and it is experimental feature. This is not supported in current browsers but by using Babel we can use it.

But we can create our own custom pipeline method.

## DEFINITION
Pipeline is the process initiated by some payload and this payload will be passed from stage to stage in order to complete the required process.

## USAGE
Sometime we need to do more operations with different functions to get required result. But we can't write all those operations logics inside only one function. We need to write different operations in different functions because they might be reusable functions. So we have to use those functions consecutively one by one by getting previous function result.

Using pipeline will not only allow constructing reusable pipelines but also result in comparatively cleaner and readable code. It helps to do consecutive operations like consecutive function calls. Without pipeline method also we can achieve what we want but these styles differ much in readability, fluency, and applicability.

## EXAMPLE
Let's take one example, i.e take three functions having names `sum`, `multiple` and `subtract` where sum have parameter number `5` and remaining functions have parameters those what we get from previously called functions. i.e call the `sum` function with parameter entered by user (let's take 5), and next call the `multiple` function should call with parameter what we returned from `sum` function. In that same way call the `subtract` function with parameter what we returned from `multiple` function. 

Simply this is called functional chaining i.e one function returned value should be another function parameter.

```js
const sum=(num)=> {
   return num + 10
}
const multiple=(num)=>{
   return num * 10
}
const subtract=(num)=>{
   return num - 10
}
```
Let's assume if user pass 5 to `sum` function, first of all we have to call `sum` function with parameter `5` and it should returns `15` (5 + 10), later we have to call `multiple` function with parameter what we get from sum function i.e `15` and it should returns `150`  (15 * 10) and later have to call `subtract` function with parameter what we get from multiple function i.e `150` and should return `140` (150 - 10). Finally this is the result what we want from consecutive calls of functions.

<u>Callback Method</u>
```js
const res = subtract(multiple(sum(5)))
console.log(res)                           //output : 140
```
Let me explain above code step by step.
```js
const sumRes = sum(5)                      //output : 15
const multipleRes = multiple(sumRes)       //output : 150
const res = subtract(multipleRes)          //output : 140
console.log(res)

```
If we observe the above code the flow of execution moves right to left, rather than the left to right reading of normal code. If there are multiple arguments at some levels, reading even bounces back and forth. editing the code afterwards can be fraught. We must find the correct place to insert new arguments among many nested parentheses.

So here comes the pipeline method

<u>Pipeline Method One</u>

```js
const pipeline = (...fns) => fns.reduce((acc, fn) => {
    try {
        return fn(acc)
    } catch (error) {
        return error.message
    } 
})

const res = pipeline(5, sum, multiple, subtract)
console.log(res)                         //output : 140
```

We know that reduce method gets two arguments first one is accumulator (`acc`) and second one is current value (`fn`). Here first `acc` value is first value of array i.e `5` because we are not providing any initial value and `fn` is nothing but second value of array nothing but `sum` and by using both we are calling `sum(5)` and the returned value saved as `acc` and `fn` will become `multiple` and both returns as another function and it is repeated process.

<u>Pipeline Method Two</u>
```js
export const pipeline = (...fns) => (val) => 
fns.reduce((prev, fn) => {
    try {
        return fn(prev)
    } catch (error) {
        return error.message
    }
}, val)

const res = pipeline(sum, multiple, subtract)(5)
console.log(res)                   //output : 140
```
This is another simple pipeline method by using `function currying`.

## ANOTHER EXAMPLE
```js
const arr1 = [1, 2, 3, 4, 5]
const arr2 = [1, 'a', 3, 4, 5]
const arr3 = [1, 2, 3, -4, 5, 6]

const checkString = (arr) => {
    if (arr.every(item => typeof item === 'number')) {
        return arr
    } else {
        return 'Array contains strings'
    }
}
const checkNegatives = (arr) => {
    if (arr.every(item => item >= 0)) {
        return arr
    } else {
        return 'Array contains negative values'
    }
}

const sum = (arr) => {
    return arr.reduce((acc, curr) => curr + acc)
}

const pipeline = (...fns) => fns.reduce((acc, fn) => {
    try {
        return fn(acc)
    } catch (error) {
        return acc
    } j
})

const res1 = pipeline(arr1, checkString, checkNegatives, sum) 
console.log(res1)    //output : 15

const res2 = pipeline(arr2, checkString, checkNegatives, sum)
console.log(res2)   //output : 'Array contains strings'

const res3 = pipeline(arr3, checkString, checkNegatives, sum) 
console.log(res3)  //output : 'Array contains negative values'
```