写了多年的js,遇到过最蛋疼的事情莫过于callback hell, 相信大家也感同身受。
业界许多大大也为此提出了很多不错的解决方案,我所了解的主要有:
我这人闲着没事也爱折腾,我也自己造轮子,不为别的只为自己代码写的舒服流畅.
传送门:目前只支持 node.js 环境,以后有时间再增加浏览器支持
为啥叫avQ: 全称是avril.queue因为哥喜欢avril就用她名字命名,跟岛国无关
核心:avQ作为一个异步流程控制框架包含两大要素来实现异步流程控制并且编码方便流畅
var q = avQ();var $fileContent = q.$await(fs.readFile, 'the/path/of/file.txt', function(err, res){ /*此时的this 并不是指向q,而是一个新的avQ()对象 所以this实际上就是一个subQueue, this.error()会将error层层上抛默认只上抛不做任何处理,以后章节我会详细介绍q.func执行的原理*/ this.error(err); return res;});
如果fs.readFile 需要上下文怎么办
q.$await, q.$each, 以及后面的q.$$await,q.$$each 都支持传入context作为第一个参数,例如
var $fileContent = q.$await(fs, fs.readFile, 'the/path/of/file.txt', function(err, res){ this.error(err); return res;});var $$fileContent = q.$$await(fs, fs.readFile, 'the/path/of/file.txt'); // 会自动将 res 最为 $awaitData 的结果var $fileExisted = q.$await(fs.exists, 'the/path/of/file.txt'); // 默认将返回fs.existe 的 callback(existed) 中第一个参existed 数作为值
var avQ = require('avril.queue');var q = avQ(); /* return $AwaitData object */var $fileContent = q.$await(fs.readFile, 'the/path/of/file.txt', function(err, fileContent){ this.error(err); return fileContent;});/* convert the $awaitData' result , return a new $AwaitData object */var $ids = $fileContent.convert(function($org){ return $org.result().split('/n');}); /* return $AwaitData object which result is list of */var $users = q.$each(db.User.findById, $ids, function(err, user){ this.error(err); return user;}); q.func(function(){ console.log( $fileContent.result() ) console.log( $users.realResult() );});
对于标准的node.js异步调用一般返回值是callback(err, result),
var $fileContent = q.$$await(fs.readFile, 'the/path/of/file.txt'); // 跟$await() 的区别在于$await 最后一个参数需要callback: return res;
$fileContent在异步请求完毕之后将会自动使用result 作为结果.
var avQ = require('avril.queue');var q = avQ();var $fileContent, $ids, $users;/* return $AwaitData object */var filePath1 = 'the/path/of/file1.txt';var filePath2 = 'the/path/of/file2.txt';var $fileExisted = q.$await(fs.exists, filePath1);q.$if($fileExisted, function(){ $fileContent = this.$$await(fs.readFile, filePath1);}).$else(function(){ $fileContent = this.$$await(fs.readFile, filePath2);});q.func(function(){ /* convert the $awaitData' result , return a new $AwaitData object */ $ids = $fileContent.convert(function($org){ return $org.result().split('/n'); }); /* return $AwaitData object which result is list of */ $users = this.$$each(db.User.findById, $ids); });q.func(function(){ console.log( $fileContent.result() ) //只取出第一级 result() console.log( $users.realResult() ); // 递归取出所有的result()});
人无完人,码无完码,欢迎大家拍砖,如果大家有兴趣我会继续推出更多api文档及介绍(大家没兴趣还是要继续写完整,哈哈).
大家要觉得我这个库有意思不妨给个github start
新闻热点
疑难解答