废话前言

写了多年的js,遇到过最蛋疼的事情莫过于callback hell, 相信大家也感同身受。

业界许多大大也为此提出了很多不错的解决方案,我所了解的主要有:

  • 朴灵 event proxy, 简单明了容易上手
  • 老赵的 wind.js, 写起来最舒坦,最能表达程序顺序执行逻辑
  • Promise,个人感觉为解决一个坑引入另外一个坑,写出来的代码一大坨,代码可读性最差

我这人闲着没事也爱折腾,我也自己造轮子,不为别的只为自己代码写的舒服流畅.

传送门:目前只支持 node.js 环境,以后有时间再增加浏览器支持

简介

为啥叫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)的更多相关文章

  1. js异步流程控制-回调

    f1为耗时操作,f2依赖f1的数据,因此f2必须在f1之后执行: 个人理解是:将f2(回调函数)的代码放在异步函数内部的最后执行,相当于把同步操作的代码融合到异步函数内部的最后: let tag = ...

  2. nodejs进阶(7)—async异步流程控制

    Async介绍 Async是一个流程控制工具包,提供了直接而强大的异步功能.基于Javascript为Node.js设计,同时也可以直接在浏览器中使用. Async提供了大约20个函数,包括常用的 m ...

  3. 使用yield进行异步流程控制

    现状 目前我们对异步回调的解决方案有这么几种:回调,deferred/promise和事件触发.回调的方式自不必说,需要硬编码调用,而且有可能会出现复杂的嵌套关系,造成"回调黑洞" ...

  4. 异步流程控制库GoWithTheFlow

    异步流程控制库GoWithTheFlow 一个尾触发方式来控制异步流程的库, 有seq(顺序执行) par(同步执行) 两种方法 博客 http://notes.jetienne.com/2011/0 ...

  5. 【javascript】Promise/A+ 规范简单实现 异步流程控制思想

    ——基于es6:Promise/A+ 规范简单实现 异步流程控制思想  前言: nodejs强大的异步处理能力使得它在服务器端大放异彩,基于它的应用不断的增加,但是异步随之带来的嵌套.难以理解的代码让 ...

  6. node核心:异步流程控制

    Node.js的异步是整个学习Node.js过程中重中之重. 1)异步流程控制学习重点 2)Api写法:Error-first Callback 和 EventEmitter 3)中流砥柱:Promi ...

  7. Nodejs中使用异步流程控制Async

    首先,我们都知道,Node基于事件驱动的异步I/O架构,所谓异步就是非阻塞,说白了就是一个事件执行了,我不必等待它执行完成后我才能执行下一个事件.所以在Node环境中的模块基本都是异步的,上一篇说到我 ...

  8. (一)Nodejs - 框架类库 - Nodejs异步流程控制Async

    简介 Async是一个流程控制工具包,提供了直接而强大的异步功能 应用场景 业务流程逻辑复杂,适应异步编程,减少回调的嵌套 安装 npm insatll async 函数介绍 Collections ...

  9. async 异步流程控制规则

    github 学习async网址 : https://github.com/caolan/async/ 1.Async 函数介绍 async 主要实现了三个部分的流程控制功能 1.集合:Collect ...

随机推荐

  1. php中12个魔术方法

    本文列举了php面向对象当中12个魔术方法,并对此进行一一详细介绍,希望对新手有所帮助. 1.构造方法: __construct() 参数:自定义 触发时机:new的一瞬间自动调用 作用:初始化成员属 ...

  2. MySQL用户管理语句001

    总的来说mysql的用户管理方法可以分为如下两种: 1.直接对mysql.user 表进行[insert | update | delete] + flush privileges 这种方式主要针对那 ...

  3. jsp执行数据库查询并分页

    需求: 有一批企业的基本信息需要展示出来,要求一级页以列表形式展示企业清单,点击公司名称后进入二级页面,二级页面展示企业简介和几张图片. 实现效果: 开发环境: Win7,Eclipse,Mysql ...

  4. 对发给Application.Handle消息的三次执行(拦截)消息的过程

    unit Main; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms ...

  5. Linux下,连接器ld链接顺序的总结

    原来ld对于链接一系列的库的顺序是很敏感的,不然会报undefined referenced 的函数符号错误,意思就是未找到函数定义.实际上库是能正确打开的.如果库libA.a依赖于库libB.a,那 ...

  6. hdu 4620 Fruit Ninja Extreme

    Fruit Ninja Extreme Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. Validate Binary Search Tree 解答

    Question Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is d ...

  8. cc150 Chapter 2 | Linked Lists 2.6 Given a circular linked list, implement an algorithm which returns node at the beginning of the loop.

    2.6Given a circular linked list,  implement an algorithm which returns the node at the beginning of ...

  9. Unity 使用实体类

    故事的由来: 正在开发打飞机的游戏,遇到这样的数据结构,游戏有很多关卡-> 每个关卡有几波怪物->每一波里面有怪物和数量 [] 关卡 { []波{ {怪物,数量},{怪物,数量},{怪物, ...

  10. Android应用程序与SurfaceFlinger服务的关系概述和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7846923 SurfaceFlinger服务负 ...