DEV Community

Cover image for JavaScript Pipeline
sundarbadagala
sundarbadagala

Posted on • Edited on

JavaScript Pipeline

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.

const sum=(num)=> {
   return num + 10
}
const multiple=(num)=>{
   return num * 10
}
const subtract=(num)=>{
   return num - 10
}
Enter fullscreen mode Exit fullscreen mode

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.

Callback Method

const res = subtract(multiple(sum(5)))
console.log(res)                           //output : 140
Enter fullscreen mode Exit fullscreen mode

Let me explain above code step by step.

const sumRes = sum(5)                      //output : 15
const multipleRes = multiple(sumRes)       //output : 150
const res = subtract(multipleRes)          //output : 140
console.log(res)

Enter fullscreen mode Exit fullscreen mode

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

Pipeline Method One

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
Enter fullscreen mode Exit fullscreen mode

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.

Pipeline Method Two

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
Enter fullscreen mode Exit fullscreen mode

This is another simple pipeline method by using function currying.

ANOTHER EXAMPLE

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'
Enter fullscreen mode Exit fullscreen mode

Top comments (0)