js异步并行和串行

最近学了学webpack的插件,其实挺简单的,webpack本质上是一种事件流机制,核心是tapable(不是table),通过事件的注册和监听,触发函数方法。所以写插件就是通过暴露给我们的方法去注册和调用。

tapable主要是同步和异步,异步分为并行和串行,今天主要是学习一下异步的并行和串行,才能更好理解tapable。现在实现异步的有很多,比如promise、generator、async await,用这些去实现异步的并行和串行非常简便,promise的all方法就是异步的并行。

异步并行:
我觉得应该不需要解释,就是几个异步同时执行,最后一个执行完毕调用一下回调方法,简单实现:

class AsyncParallel{
    constructor() {
        this.cbList = [];
    }
    tap(fn) {
        this.cbList.push(fn);
    }
    call(end){
        let index = 0;
        this.cbList.forEach(fn => {
            fn(() => {
                index++;
                if(index === this.cbList.length){end()};
            });
        })
    }
}
let ap = new AsyncParallel();
ap.tap((cb) => {
    setTimeout(() => {
        console.log(1);
        cb();
    }, 3000)
})
ap.tap((cb) => {
    setTimeout(() => {
        console.log(3);
        cb();
    }, 1000)
});
ap.call(() => {
    console.log('end');
})

异步串行:
第一个执行完执行下一个,其实就是用一个next方法去判断执行下一个,简单实现:

class AsyncSerial{
    constructor() {
        this.cbList = [];
    }
    tap(fn) {
        this.cbList.push(fn);
    }
    call(end){
        let index = 0;
        let next = () => {
            if(index === this.cbList.length){
                end();
                return;
            }
            let fn = this.cbList[index];
            fn(() => {
                index++;
                next();
            })
        }
        next();
    }
}
let ap = new AsyncSerial();
ap.tap((cb) => {
    setTimeout(() => {
        console.log(1);
        cb();
    }, 3000)
})
ap.tap((cb) => {
    setTimeout(() => {
        console.log(3);
        cb();
    }, 2000)
});
ap.call(() => {
    console.log('end');
})

大概就是这样,继续扩展就会复杂很多,比如是否要把结果传递下去,中间报错是否就终止,返回值如果不是undefined是否继续等,如果使用promise会更简单一些。然后建议去看看tapable,里面可以实现的会更多跟复杂,如果想学习webpack内部一些机制,tapable是一定要了解的。

js异步并行和串行_第1张图片

你可能感兴趣的:(js异步并行和串行)