异步串行 —— AsyncSeriesWaterfallHook

上一个监听函数的中的callback(err, data)的第二个参数,可以作为下一个监听函数的参数

7.use.js

let {AsyncSeriesWaterfallHook} = require('tapable')   // 解构同步勾子


class Lesson {
    constructor() {
        this.index = 0
        this.hooks = {
            // 订阅勾子
            arch: new AsyncSeriesWaterfallHook(['name']),

        }
    }

    start() {
        // 发布
        this.hooks.arch.callAsync('may', function () {
            console.log('end');
        })
        // 另一种发布
        // this.hooks.arch.promise('may').then(function () {
        //         console.log('end');
        //     }
        // )
    }

    tap() {   //  注册监听函数,订阅
        this.hooks.arch.tapAsync('node',  (name, callback) => {
            setTimeout(() => {
                console.log('node', name)
                // callback(null, 'result')
                callback('error', 'result')   // 如果放error, 会跳过直接后面的勾子,直接走到最终的

            }, 1000)
        })
        this.hooks.arch.tapAsync('react',  (name, callback) => {
            setTimeout(() => {
                console.log('react', name)
                callback()
            }, 1000)
        })
        // 另一种订阅
        // this.hooks.arch.tapPromise('node', (name) => {
        //     return new Promise((resolve, reject) => {
        //         setTimeout(() => {
        //             console.log('node', name)
        //             resolve()
        //         }, 1000)
        //     })
        // })
        // this.hooks.arch.tapPromise('react', (name) => {
        //     return new Promise((resolve, reject) => {
        //         setTimeout(() => {
        //             console.log('react', name)
        //             resolve()
        //         }, 1000)
        //     })
        // })
    }
}


let l = new Lesson()

l.tap();  //注册两个函数
l.start(); // 启动勾子

7.theory.js

class AsyncSeriesWaterfallHook {  //
    constructor(args) {  // args => ['name']
        this.tasks = []
    }

    tapAsync(name, task) {
        this.tasks.push(task)
    }

    tapPromise(name, task) {
        this.tasks.push(task)
    }
    callAsync(...args) {
        let finalCallback = args.pop()
        let index = 0;
        let next = (err, data) => {
            let task = this.tasks[index]
            if(!task) return finalCallback();
            if (index === 0) {
                // 执行的第一个
                task(...args, next)
            } else {
                task(data, next)
            }
            index ++
        }
        next();
    }

    promise(...args) {
        // 将promise串联起来
        let [first, ...other] = this.tasks
        return other.reduce((p, n) => {
             return p.then((data) => n(data))
        }, first(...args))
    }
}

let hook = new AsyncSeriesWaterfallHook(['name'])


// hook.tapAsync('react', function (name, callback) {
//     setTimeout(() => {
//         console.log('react', name);
//         callback(null, '结果1')
//     }, 1000)
// })
//
// hook.tapAsync('node', function (name, callback) {
//     setTimeout(() => {
//         console.log('node', name);
//         callback(null, '结果2')
//     }, 1000)
// })
//
// hook.tapAsync('webpack', function (name, callback) {
//     setTimeout(() => {
//         console.log('webpack', name);
//         callback()
//     }, 1000)
// })

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

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


//
//
// hook.callAsync('jw', function () {
//     console.log('end');
// })


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

results matching ""

    No results matching ""