花了几个周末,新开源一个库

这个库名字叫 easytask,它的作用是能够让同步或异步任务写起来更方便,解决这几个痛点,我例举几个:

1、当页面弹窗比较多的时候,如何判断该弹哪一个弹窗,有的弹窗条件是同步方法,比如通过存储在 localstorage 的一个 key 来判断(同步);有的需用通过接口判断(异步);面对这种异步与同步混合的任务你该如何做?停顿几秒,思考一下你以前是如何解决这类问题的。

2、网络请求依赖,比如登录后,获取用户信息,然后通过不同的用户显示不同的页面逻辑,3个网络请求,如何做到串行执行,并且后一个网络请求需要依赖前一个网络请求的结果。停顿几秒,思考一下你以前是如何解决这类问题的。

3、有 10 个网络请求,如何控制它的并发数,一次只能执行两个任务,等所有的任务执行完后把所有的结果返回。

流水线控制任务的串行执行

以上这几个例子,最简单的方法就是各种 if - else 判断,然后满足条件后执行其它任务,但其实可以把以上这些过程进行「抽象化」。我们看下解决串行任务时,easytask 做的事情:

流水线,可以解决网络串行执行依赖问题和任务串行执行:

创建一个流水线,并初始化一个数据 data,这个 data 在每个任务中可以使用

let data = {};
let pipeline = new Pipeline(data);

添加一个同步任务,如果需要执行下一个任务,需要手动调用 next 函数

pipeline.use((data, next) => {
    doSomething();
    // run next task
    next();
});

添加一个异步任务,并在 data 中添加一个数据,这样下一个任务可以直接使用这个数据

pipeline.use((data, next) => {
    setTimeout(() => {
        // you can change data, add property taskId to data
        data.taskId = 'everydata';
        next();
    }, 200);
});

再添加一个异步任务

// add sync task to pipeline
pipeline.use(function (data, next) {
    if (data.taskId) {
        // find the task, stop run
    }
    else {
        next();
    }
});

开启任务执行,所有的任务执行顺序是按照添加顺序一个一个执行,下一个任务是否要执行,完全由使用者通过 next 函数来控制

// the task begin run
pipeline.run();

队列控制任务的串行与并行执行

队列与流水线的主要区别是,队列中的任务是自动执行的,而流水线的下一个任务执行需要使用者调用 next 函数:

Queue 中提供了 3 个函数:

第 1 个 queue.race:

race(this: any, tasks: Task[]): Promise<any>;

任务串行执行,只要有一个任务 resolve 一个真值,那么整个队列将停止,返回一个 Promise 对象,你可以这样使用:

一个同步任务,函数的返回值为任意对象,为真时队列将停止执行:

const everyDay = (data) => {
    return false;
};

一个异步任务,需要返回一个 Promise,resolve 为真时,队列将停止执行:

const newUser = (data) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('new user');
        }, 100);
    });
};

一个异步任务,需要返回一个 Promise

const vip = (data) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('vip');
        }, 10);
    });
};

创建一个队列,并执行这些任务,第2个任务返回一个真值,第 2 个任务获胜

let queue = new Queue();
// 创建一个任务数组
let tasks = [everyDay, newUser, vip];
// 开始执行任务
queue.race(tasks).then(res => {
    // 第2个任务返回一个真值,第 2 个任务获胜
    console.log('queue finished =', res);
}).catch(error => {
    console.log('error = ', error);
});

第 2 个 queue.serial:

serial(this: any, tasks: Task[]): Promise<any>;

和流水线差不多,任务串行执行,知道所有的任务执行完才队列才会停止,并返回每个任务执行的结果。

一个同步任务,函数的返回值为任意对象:

const everyDay = (data) => {
    return false;
};

一个异步任务,需要返回一个 Promise

const newUser = (data) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('new user');
        }, 100);
    });
};

一个异步任务,需要返回一个 Promise

const vip = (data) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('vip');
        }, 10);
    });
};

创建一个队列,并执行这些任务

let queue = new Queue();
let tasks = [everyDay, newUser, vip];
queue.serial(tasks).then(res => {
    // res {
    //     0: false,
    //     1: new user,
    //     2: vip
    // }
    console.log('queue finished =', res);
}).catch(error => {
    console.log('error = ', error);
});

第 3 个 queue.parallel:

parallel(this: any, tasks: Task[], limit: number): Promise<any>;

队列中的任务并行执行,通过参数控制并发数:

一个同步任务,函数的返回值为任意对象:

const everyDay = (data) => {
    return false;
};

一个异步任务,需要返回一个 Promise

const newUser = (data) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('new user');
        }, 100);
    });
};

一个异步任务,需要返回一个 Promise

const vip = (data) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('vip');
        }, 10);
    });
};

创建一个队列,并执行这些任务,一次只能并发执行两个任务

let queue = new Queue();
let tasks = [everyDay, newUser, vip];
queue.parallel(tasks, 2).then(res => {
    // res {
    //     0: false,
    //     1: new user,
    //     2: vip
    // }
    console.log('queue finished =', res);
}).catch(error => {
    console.log('error = ', error);
});

以上是我为解决此类问题创建的一个开源库,如果有不妥的地方,欢迎大家吐槽,代码已提交,如果未收到任何人的吐槽,我将发布一个 npm 包。单测覆盖 100%,可放心使用,有问题肯定会及时响应。

项目地址:https://github.com/lefex/easytask

长按关注

素燕《前端小课》

帮助 10W 人入门并进阶前端

官网:https://lefex.gitee.io/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值