JS 异步编程之三:理解 Co.js
作者:nunumick 发布时间:05 Aug 2017 分类: front-end
Co.js 是 TJ 大神基于 Generator 特性写的 js 库,可以用同步的方式编写和执行异步函数,核心代码只有几十行。
其本质上就是一个迭代器的执行函数,来看下面个人仿制的简写代码,理解精髓即可:
// 定义一个生成器,包含我们要用到的异步函数
const gen = function* () {
let a = yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve(10);
}, 1000);
});
let b = yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve(20);
}, 2000);
});
let c = yield new Promise((resolve, reject) => {
setTimeout(() => {
resolve(15);
}, 1000);
});
let d = yield 5;
let e = a + b + c + d;
console.log(e);
return e;
};
//编写一个递归执行的通用迭代器执行函数
//第一个入参为要执行的生成器,第二入参为 next 赋值
const iter = function (gen, value) {
let item = gen.next(value);
let v = item.value;
console.log(item);
if (item.done) return Promise.resolve(v);
//这一步很关键,如果是异步函数,则返回v.then
if (v instanceof Promise) {
return v.then((res) => {
return iter(gen, res);
});
} else {
console.log(v);
return iter(gen, v);
}
};
//co就是对执行器的再一次包装
const co = function (gen) {
let g = gen();
return iter(g);
};
//test
co(gen).then((res)=>{
console.log(res);
})
用 co 重写代码
有了这个可重用的便捷的 co 执行器,我们可以用它来重写上一篇理解生成器(generator) 文中的样例代码,替换掉手动逐行执行的那部分。
let [s1, s2, s3, s4] = [2000, 500, 0, 100];
const promiseA = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("t1:", time);
resolve(time);
}, time);
});
};
const promiseB = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("t2:", time);
resolve(time);
}, time);
});
};
const promiseC = (time) => {
return new Promise((resolve, reject) => {
console.log("t3:", time);
resolve(time);
});
};
const promiseD = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("t4:", time);
resolve(time);
}, time);
});
};
//对比下这段
co(function* () {
let t1 = yield promiseA(s1);
let t2 = yield promiseB(t1 + s2);
let t3 = yield promiseC(t2);
let t4 = yield promiseD(t1);
let result = yield co(gen).then((t5) => {
return Promise.resolve(t3 + t4 + t5);
});
return result;
}).then((res) => {
console.log("result:", res);
});
co 执行器为开发者提供了极大的便利性,让代码变的短小精悍、简洁明了,我们可以专注于生成器内部的代码逻辑,无需关注迭代执行流程,这就是早期的异步编程同步写法。ES2017 官方发布 async & await 后,异步编程更加轻松,co.js 退出历史舞台。
标签:
javascript
,
co
<<< EOF