每次写出一个好玩具总忍不住来社区分享一下 ^-^
前天突发奇想,要是仅基于ES5就可以以同步的方式书写异步逻辑就太方便了,不用去转译,不用考虑兼容性问题,前端同学也可以直接用。目前 有 基于ES6 generator 的方案 和 ES7 的async /await 语法。之前也基于generator写过一个 zco , 非常好用,但写前端逻辑就歇菜了,手机上运行失败,不支持yield语法。。。
异步逻辑烦在不能书写同步的代码获得运行结果,只能通过回调(回调是js的精髓之一),这样的逻辑多了,代码甚是难看,这个废话想必看官都非常了解。
我们知道代码是异步执行的,但我们想书写时是同步的形式。 对,是形式上的同步。 问题的关键是如何实现形式上的同步。ES6可以借助yield ,ES5可不支持,唯一的途径是创造形式,以一种新的观念书写逻辑:
一个操作指令由操作方法,参数,返回值三大部分组成,无论异步还是同步函数都是如此。差别在于异步函数获取返回值的方式,这也是所需要克服的最大的难点。 如果先编写指令,获得指令序列之后再按书写的逻辑顺序去执行指令,那么异步与同步的差别就可以在库的内部予以屏蔽。
基于这样的想法做了一下实现。下面是以浏览器中异步网络操作为背景演示一下:
cc(function(exec,ctx,resume){
//使用jquery的post方法搜索关键词cc,并将结果命名为result
exec.async($.post).assign("result")("/search",{"key":"cc"},resume);//resume充当原$.post方法的回调函数
exec(function(){
// 通过ctx获得上一步的执行结果,取得关键词对应的详细信息的地址,发起get请求获取详细信息
exec.async($.get).assign("detail")( ctx.result.detail,resume);
});
exec(function(){
// 打印详细信息
console.log(ctx.detail);
});
})()
可以fake一下post和get方法自己测试一下,项目地址在:https://github.com/yyrdl/cc,
在浏览器中测试只需引入项目下的cc.min.js,node.js用户可以直接 npm install cc_co
, const cc = require("cc_co")
;
上面代码中的exec
每一次执行都生成一条指令(其中assign对应返回值),待指令生成完毕之后cc会按书写的逻辑顺序依次去执行。
刚发布第一版,欢迎一起交流 :) 我也不知道有多少意义,先作为一个玩具玩