js 异步流程控制之 avQ(avril.queue)
废话前言
写了多年的js,遇到过最蛋疼的事情莫过于callback hell, 相信大家也感同身受。
业界许多大大也为此提出了很多不错的解决方案,我所了解的主要有:
- 朴灵 event proxy, 简单明了容易上手
- 老赵的 wind.js, 写起来最舒坦,最能表达程序顺序执行逻辑
- Promise,个人感觉为解决一个坑引入另外一个坑,写出来的代码一大坨,代码可读性最差
我这人闲着没事也爱折腾,我也自己造轮子,不为别的只为自己代码写的舒服流畅.
传送门:目前只支持 node.js 环境,以后有时间再增加浏览器支持
- github https://github.com/flowforever/avril.queue
- npm install avril.queue
简介
为啥叫avQ: 全称是avril.queue因为哥喜欢avril就用她名字命名,跟岛国无关
核心:avQ作为一个异步流程控制框架包含两大要素来实现异步流程控制并且编码方便流畅
- queue 执行队列 确保程序逻辑按照顺序执行
- $AwaitData 异步等待数据对象,该对象可以作为参数用于下一步异步请求,实现编码流畅的核心
动手avQ
Basic example: q.func, q.$await, q.$each
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() );
});
Syntax Sugar: q.$$await, q.$$each,
q.$if($awaitData, trueFunc), q.$if($awaitData, trueFunc).$else(), q.$if($awaitData, trueFunc).$elseIf($otherAwaitData, otherTrueFunc)
对于标准的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
js 异步流程控制之 avQ(avril.queue)的更多相关文章
- js异步流程控制-回调
f1为耗时操作,f2依赖f1的数据,因此f2必须在f1之后执行: 个人理解是:将f2(回调函数)的代码放在异步函数内部的最后执行,相当于把同步操作的代码融合到异步函数内部的最后: let tag = ...
- nodejs进阶(7)—async异步流程控制
Async介绍 Async是一个流程控制工具包,提供了直接而强大的异步功能.基于Javascript为Node.js设计,同时也可以直接在浏览器中使用. Async提供了大约20个函数,包括常用的 m ...
- 使用yield进行异步流程控制
现状 目前我们对异步回调的解决方案有这么几种:回调,deferred/promise和事件触发.回调的方式自不必说,需要硬编码调用,而且有可能会出现复杂的嵌套关系,造成"回调黑洞" ...
- 异步流程控制库GoWithTheFlow
异步流程控制库GoWithTheFlow 一个尾触发方式来控制异步流程的库, 有seq(顺序执行) par(同步执行) 两种方法 博客 http://notes.jetienne.com/2011/0 ...
- 【javascript】Promise/A+ 规范简单实现 异步流程控制思想
——基于es6:Promise/A+ 规范简单实现 异步流程控制思想 前言: nodejs强大的异步处理能力使得它在服务器端大放异彩,基于它的应用不断的增加,但是异步随之带来的嵌套.难以理解的代码让 ...
- node核心:异步流程控制
Node.js的异步是整个学习Node.js过程中重中之重. 1)异步流程控制学习重点 2)Api写法:Error-first Callback 和 EventEmitter 3)中流砥柱:Promi ...
- Nodejs中使用异步流程控制Async
首先,我们都知道,Node基于事件驱动的异步I/O架构,所谓异步就是非阻塞,说白了就是一个事件执行了,我不必等待它执行完成后我才能执行下一个事件.所以在Node环境中的模块基本都是异步的,上一篇说到我 ...
- (一)Nodejs - 框架类库 - Nodejs异步流程控制Async
简介 Async是一个流程控制工具包,提供了直接而强大的异步功能 应用场景 业务流程逻辑复杂,适应异步编程,减少回调的嵌套 安装 npm insatll async 函数介绍 Collections ...
- async 异步流程控制规则
github 学习async网址 : https://github.com/caolan/async/ 1.Async 函数介绍 async 主要实现了三个部分的流程控制功能 1.集合:Collect ...
随机推荐
- 更有效率的使用 Visual Studio - 快捷键
工欲善其事,必先利其器.虽然说Vim和Emacs是神器,但是对于使用Visual Studio的程序员来说,我们也可以通过一些快捷键和潜在的一些功能实现脱离鼠标写代码,提高工作效率,像使用Vim一样使 ...
- Taglib、EL、OGNL
Taglib.EL.OGNL 阅读目录 1. Taglib(tag library) 标签库 2. EL(Expression Language) 表达式 3. OGNL(Object-Graph N ...
- IE6 js修改img的src属性问题
今天在做项目,有个点击按钮切换图片功能,即修改img的src属性,在IE6下测试,切换图片不显示,右键选择显示图片,可以显示出来,琢磨了很久,最终发现是因为该按钮是a标签导致的, 随后上网查了下,有些 ...
- QT自定义窗口(模拟MainWindow)
在这里自定义窗口是通过继承于QFrame,内部分为上下两部分,上半部分就是标题栏,下面是窗口的具体内容.上下两部分通过布局固定位置.最后窗口的各种鼠标拖动,缩放,等操作通过添加鼠标事件来完成一个窗口的 ...
- CSS之Hack
一.类内部Hack IE都能识别*;标准浏览器(如FF)不能识别*:IE6能识别*,但不能识别 !important, IE7能识别*,也能识别!important; FF不能识别*,但能识别!imp ...
- Android的debug.keystore拒绝访问导致的生成异常及解决方案
构建Android应用程序的时候输出异常:[apkbuilder] keytool 错误: java.io.FileNotFoundException: C:\Users\my\.android\de ...
- 安装 Kali Linux 后需要做的 20 件事
安装 Kali Linux 后需要做的 20 件事 本文含有我觉得有用的每一件事情.本文分为三大部分: 专门针对Kali用户 Kali Linux是来自Debian的一个特殊版本,Kali Linux ...
- COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)
声明:本文代码基于CodeProject的文章<A Complete ActiveX Web Control Tutorial>修改而来,因此同样遵循Code Project Open L ...
- windows多线程没那么难
windows多线程没那么难 作者:vpoet mail:vpoet_sir@163.com 上一博文中我们引入了CreateThread()多线程编程一个简单的例子,事实上我说windows 多线程 ...
- 格而知之7:我所理解的Runtime(2)
消息发送(Messaging) 8.以上便是runtime相关的一些数据结构,接下来我们回看一开始的疑问: objc_msgSend()函数在执行的过程中是如何找到对应的类,找到对应的方法实现的呢? ...