Web Pack 4 Learning Path-9

Keywords: Java React Webpack

Tapable

Webpack is essentially an event flow mechanism. Its workflow is to connect plug-ins in series. The core of Webpack is Tapable, which is a bit like the event library of nodejs, and mainly depends on the publisher-subscriber mode.

The difference between hook function and callback function

Hook function: executes at the first time of capturing a message.
Callback function: At the end of capture, it is finally executed

SyncHook

- 1.start.js

let { SyncHook } = require('tapable')

class Lession {
    constructor() {
        this.hook = {
            arch: new SyncHook(['name'])
        }
    }
    tap() { //Registered listener function
            this.hook.arch.tap('lheng', (name) => {
                console.log('node', name);

            })
            this.hook.arch.tap('wting', (name) => {
                console.log('wting', name);

            })
        } //When tap is used, two listening events are added to the array
    start() {
        this.hook.arch.call('lheng')
    }
}

let l = new Lession()
l.tap() //Register these two events
l.start() //Start hook

Implementing SyncHook

class SyncHook { //Synchronized hook
    constructor(args) { //args => ['name]
        this.tasks = []
    }
    call(...args) {
        this.tasks.forEach((task) => task(...args))
    }
    tap(name, task) {
        this.tasks.push(task)
    }
}

let hook = new SyncHook(['name'])
hook.tap('react', function(name) {
    console.log('react', name);
})
hook.tap('java', function(name) {
    console.log('java', name);
})
hook.call('lheng')

SyncBailHook

Synchronized insurance hook, where execution is terminated if the return value of a function in the middle is not undefined

let { SyncBailHook } = require('tapable')

class Lession {
    constructor() {
        this.hook = {
            arch: new SyncBailHook(['name'])
        }
    }
    tap() { //Registered listener function
            this.hook.arch.tap('lheng', (name) => {
                console.log('node', name);
                return 'stop'
            })
            this.hook.arch.tap('wting', (name) => {
                console.log('wting', name);

            })
        } //When tap is used, two listening events are added to the array
    start() {
        this.hook.arch.call('lheng')
    }
}

let l = new Lession()
l.tap() //Register these two events
l.start() //Start hook

Implementing SyncBail Hook

class SyncBailHook { //Synchronized hook
    constructor(args) { //args => ['name]
        this.tasks = []
    }
    call(...args) {
        let res,
            index = 0;
        do {
            res = this.tasks[index++](...args)
        } while (res === undefined && index < this.tasks.length)
    }
    tap(name, task) {
        this.tasks.push(task)
    }
}

let hook = new SyncBailHook(['name'])
hook.tap('react', function(name) {
    console.log('react', name);
    // return 'stop'
})
hook.tap('java', function(name) {
    console.log('java', name);

})
hook.call('lheng')

SyncWaterfallHook

Waterfall flow, the result of intermediate execution will be passed on to the next

let { SyncWaterfallHook } = require('tapable')

class Lession {
    constructor() {
        this.hook = {
            arch: new SyncWaterfallHook(['name'])
        }
    }
    tap() { //Registered listener function
            this.hook.arch.tap('lheng', (name) => {
                console.log('node', name);
                return 'waterFail'
            })
            this.hook.arch.tap('wting', (data, name) => {
                console.log('wting', data, name);

            })
        } //When tap is used, two listening events are added to the array
    start() {
        this.hook.arch.call('lheng')
    }
}

let l = new Lession()
l.tap() //Register these two events
l.start() //Start hook

Result:

Reduc function introduction:
The reduce() method receives a function as an accumulator, and reduces each element in the array to perform a callback function in turn. It does not include elements deleted or never assigned in the array. It accepts four parameters: initial value (the return value of the previous callback), current element value, current index, and original array.

arr.reduce(callback,[initialValue])
callback:The function contains four parameters
- previousValue (The value returned by the last call callback, or the initial value provided( initialValue))
- currentValue (Currently processed elements in an array)
- index (Index of the current element in the array)
- array (Array of calls)
 
initialValue (As the first call callback The first parameter.)

Implementing SyncWaterfall hook

class SyncWaterfallHook { //Synchronized hook
    constructor(args) { //args => ['name]
        this.tasks = []
    }
    call(...args) {
        let [first, ...other] = this.tasks
        let res = first(...args)
        other.reduce((a, b) => {
            b(a)
        }, res)
    }
    tap(name, task) {
        this.tasks.push(task)
    }
}

let hook = new SyncWaterfallHook(['name'])
let index = 0
hook.tap('react', function(name) {
    console.log('react', name);
    // Return + index = 3?Undefined:'Continue learning'
    return 'stop'
})
hook.tap('java', function(name) {
    console.log('java', name);

})
hook.call('lheng')

SyncLoopHook

The loop executes an event until it returns undefined

let { SyncLoopHook } = require('tapable')

class Lession {
    constructor() {
        this.hook = {
            arch: new SyncLoopHook(['name'])
        }
    }
    tap() { //Registered listener function
            let index = 0
            this.hook.arch.tap('lheng', (name) => {
                console.log('node', name);

                return ++index == 3 ? undefined : 'Continue learning'
                    // return 'waterFail'
            })
            this.hook.arch.tap('wting', (name) => {
                console.log('wting', name);

            })
        } //When tap is used, two listening events are added to the array
    start() {
        this.hook.arch.call('lheng')
    }
}

let l = new Lession()
l.tap() //Register these two events
l.start() //Start hook

Implementing SyncLoophook

class SyncLoopHook { //Synchronized hook
    constructor(args) { //args => ['name]
        this.tasks = []
    }
    call(...args) {

        let res
        this.tasks.forEach((task) => {
            do {
                res = task(...args)
            } while (res != undefined)
        })
    }
    tap(name, task) {
        this.tasks.push(task)
    }
}

let hook = new SyncLoopHook(['name'])
let index = 0
hook.tap('react', function(name) {
    console.log('react', name);
    return ++index == 3 ? undefined : 'Continue learning'
        // return 'stop'
})
hook.tap('java', function(name) {
    console.log('java', name);

})
hook.call('lheng')

AsyncParallelHook

let { AsyncParallelHook } = require('tapable')
    //Async Parallel Hook Asynchronous Parallel Hook Hook
    // Parallel, sending multiple requests at the same time. After the request has been sent, a callback is executed.
    // Asynchronous hooks (serial, parallel)
    // Registration method tap registration, tapAsync registration
class Lession {
    constructor() {
        this.hook = {
            arch: new AsyncParallelHook(['name'])
        }
    }
    tap() { //Registered listener function
            let index = 0
            this.hook.arch.tapAsync('lheng', (name, cb) => {
                setTimeout(() => {

                    console.log('lheng', name);
                    cb() // Identify that the callback function has been executed, and only when all CBS have been executed will the final callback function be invoked
                }, 1000);


            })
            this.hook.arch.tapAsync('node', (name, cb) => {
                setTimeout(() => {

                    console.log('node', name);
                    // cb()
                }, 1000);

            })

        } //When tap is used, two listening events are added to the array
    start() {
        this.hook.arch.callAsync('lheng', () => {
            console.log('end');

        })
    }
}

let l = new Lession()
console.log(l);

l.tap() //Register these two events
l.start() //Start hook

Implementation of Async Parallel Hookfun1

class AsyncParallelHook { //Synchronized hook
    constructor(args) { //args => ['name]
        this.tasks = []
    }
    callAsync(...args) {
        let index = 0;
        let finalCB = args.pop() //Take out the final function.

        let done = () => { //Promise.all
            index++
            if (index == this.tasks.length) {
                finalCB()
            }
        }
        this.tasks.forEach(task => {
            task(...args, done)
        })
    }
    tapAsync(name, task) {
        this.tasks.push(task)
    }
}

let hook = new AsyncParallelHook(['name'])
let index = 0
hook.tapAsync('react', function(name, cb) {
    setTimeout(() => {
        console.log('react', name);
        cb()
    }, 1000);
    // Return + index = 3?Undefined:'Continue learning'
})
hook.tapAsync('java', function(name, cb) {
    setTimeout(() => {
        console.log('java', name);
        cb()
    }, 1000);
})
hook.callAsync('lheng', () => {
    console.log('end');

})

The difference between map and forEach
The forEach() method does not return the execution result, but undefined. That is, forEach() modifies the original array. The map() method gets a new array and returns it. Next we'll go to all Promise return values, using map naturally

Implementation of Async Parallel Hookfun2-promise

// TapAsync (cb) tapPromise is registered synchronously with tapAsync (cb) tapPromise (registration is promise)
// 			  Three methods of calling call Async promise
class AsyncParallelHook { //Synchronized hook
    constructor(args) { //args => ['name]
        this.tasks = []
    }
    promise(...args) {
        let tasks = this.tasks.map(task => {
            task(...args)
        })
        return Promise.all(tasks)
    }
    tapPromise(name, task) {
        this.tasks.push(task)
    }
}

let hook = new AsyncParallelHook(['name'])
let index = 0
hook.tapPromise('react', function(name) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('react', name);
            resolve()
        }, 1000);
    })

})
hook.tapPromise('java', function(name) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('java', name);
            resolve()
        }, 1000);
    })

})
hook.promise('lheng')
    .then(
        function() {
            console.log('end');
        }
    )

Posted by coja1 on Mon, 05 Aug 2019 02:26:50 -0700