场景
有一系列的任务函数,task1,task2....taskN,任务执行执行可异步或同步方式,实现一个run函数按照顺序依次串行执行任务;run(task1,task2....taskN)
Promise实现
调用Promise.resolve()生成resolved状态的 Promise 对象p,循环更新p,将要执行的函数task通过p.then方法进行串联,并且将执行结果push到结果数组,最后将更新的data返回,这样保证后面可以调用then方法
function runPromise(...tasks) {
const res = [];
let p = Promise.resolve();
for (let task of tasks) {
// 核心 拼接链式执行
p = p.then(con => {
res.push(con);
return task();
});
}
return p.then(con => {
res.shift();
res.push(con);
return res;
}).catch(e => {
return e;
});
}
Generator 实现
需要自己写遍历器,遍历执行
function runGenerator(...tasks) {
const res = [];
return spawn(function* () {
for (let task of tasks) {
const con = yield task();
res.push(con);
}
return res;
});
}
// 遍历器
function spawn(generatorFn) {
return new Promise((resolve, reject) => {
const gen = generatorFn(); // 遍历器对象
function step(nextFn) {
let next;
try {
next = nextFn();
} catch (error) {
return reject(error)
}
if (next.done) { // 结束直接返回
return resolve(next.value);
}
Promise.resolve(next.value).then(function (value) {
// gen.next(value) 传的参数将作为上一个yiled表达式的返回值
step(function () { return gen.next(value); });
}, function (err) { // 异常
step(function () { return gen.throw(err); })
});
}
// 启动遍历器
step(function () { return gen.next(); });
});
}
async 实现
async function runAsync(...tasks) {
const res = [];
try {
// 遍历任务 依次执行
for (let task of tasks) {
const con = await task();
res.push(con);
}
} catch (error) {
return error;
}
return res;
}
测试
function task1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 200);
});
}
function task2() {
return 2;
}
function task3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3);
}, 100);
});
}
// 输出结果 [1,2,3];
runPromise(task1, task2, task3).then(res => {
console.log(res);
});
// runGenerator(task1, task2, task3).then(res => {
// console.log(res);
// });
// runAsync(task1, task2, task3).then(res => {
// console.log(res);
// });