JavaScript 异步调用框架 (Part 5 - 链式实现)


Posted in Javascript onAugust 04, 2009

调用入口
链式调用存在Async.go方法和Async.chain方法两个入口,这两个入口本质上是一致的,只是Async.chain方法在调用时先不提供初始参数,而Async.go方法在调用时提供了初始参数并启动异步调用链。

Async.chain = function() { 
var chain = new Async.Operation({ chain: true }); 
return chain; 
}; 
Async.go = function(initialArgument) { 
return Async.chain().go(initialArgument); 
}

在这里我们可以看到,链式调用本身也是一个Async.Operation,链式调用所需的go方法和next方法都是在Async.Operation上面做的扩展,并且这个扩展不会很难,这将在下一小节说明。
扩展方法
我们都知道,通过addCallback方法添加的回调函数是会被逐一执行的,至少同步函数如此,因此我们可以用Async.Operation的这一特性来维护异步调用队列,前提是我们为它加上对异步调用进行队列的支持。
对于异步调用进行队列的支持,我们稍后再来处理,首先我们利用现成的addCallback方法和yield方法扩展出go方法和next方法。
this.go = function(initialArgument) { 
return this.yield(initialArgument); 
} 
this.next = function(nextFunction) { 
return this.addCallback(nextFunction); 
};

实际上,go方法和next方法直接调用的正是yield方法和addCallback方法。go方法的语义与yield方法一样,传递一个参数给Async.Operation实例,并且启动调用队列。同时,next方法的语义和addCallback方法,添加一个调用到队列的末端。
异步队列
如何才能让原本仅支持同步的队列变得也支持异步?这需要检测队列中的每一个调用的返回,如果返回类型为Async.Operation,我们知道是异步调用,从而使用特殊的方法等它执行完后再执行下去。
callbackResult = callback(self.result); 
self.result = callbackResult; 
if (callbackResult && callbackResult instanceof Async.Operation) { 
innerChain = Async.chain(); 
while (callbackQueue.length > 0) { 
innerChain.next(callbackQueue.shift()); 
} 
innerChain.next(function(result) { 
self.result = result; 
self.state = "completed"; 
self.completed = true; 
return result; 
}); 
callbackResult.addCallback(function(result) { 
self.result = result; 
innerChain.go(result); 
}); 
}

如果调用返回了一个Async.Operation实例,我们就利用它自身的addCallback方法帮我们执行队列中余下的调用。准确来说,是我们构造了一个新的调用链,把队列余下的调用都转移到新的调用链上,然后让当前异步调用在回调中启动这个新的调用链。
此外还有一些地方我们需要略作修改,以兼容新的异步调用队列的。例如result、state、completed的状态变更,在链式调用中是有所不同的。
小结
我们在原有的Async.Operation上略作修改,使得它支持异步调用队列,完整的代码看这里:支持链式调用的异步调用框架Async.Operation。
现在我们已经拥有了一个功能强大的Async.Operation,接下来我们就要看看如何将它投入到更多常见的使用模式中去
Javascript 相关文章推荐
浅析jQuery的链式调用之each函数
Dec 03 Javascript
JS计算网页停留时间代码
Apr 28 Javascript
浅谈Javascript的静态属性和原型属性
May 07 Javascript
Javascript模仿淘宝信用评价实例(附源码)
Nov 26 Javascript
url传递的参数值中包含&时,url自动截断问题的解决方法
Aug 02 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
Aug 12 Javascript
js微信扫描二维码登录网站技术原理
Dec 01 Javascript
Node.js利用debug模块打印出调试日志的方法
Apr 25 Javascript
javascript填充默认头像方法
Feb 22 Javascript
基于jQuery的时间戳与日期间的转化
Jun 21 jQuery
Node.js web 应用如何封装到Docker容器中
Sep 01 Javascript
如何在vue中使用HTML 5 拖放API
Jan 14 Vue.js
JavaScript 异步调用框架 (Part 4 - 链式调用)
Aug 04 #Javascript
JavaScript 异步调用框架 (Part 3 - 代码实现)
Aug 04 #Javascript
JavaScript 异步调用框架 (Part 2 - 用例设计)
Aug 03 #Javascript
JavaScript 异步调用框架 (Part 1 - 问题 & 场景)
Aug 03 #Javascript
jQuery 相关控件的事件操作分解
Aug 03 #Javascript
利用javascript实现一些常用软件的下载导航
Aug 03 #Javascript
jQuery 隔行换色 支持键盘上下键,按Enter选定值
Aug 02 #Javascript
You might like
BBS(php & mysql)完整版(一)
2006/10/09 PHP
解析PHP 5.5 新特性
2013/07/02 PHP
PHP文件缓存类示例分享
2015/01/30 PHP
Symfony2创建页面实例详解
2016/03/18 PHP
PHP实现的二分查找算法实例分析
2017/12/19 PHP
ThinkPHP框架整合微信支付之刷卡模式图文详解
2019/04/10 PHP
限制文本字节数js代码
2007/03/06 Javascript
学习JavaScript的最佳方法分享
2011/10/21 Javascript
jQuery.buildFragment使用方法及思路分析
2013/01/07 Javascript
JS性能优化笔记搜索整理
2013/08/21 Javascript
Jquery实现textarea根据文本内容自适应高度
2015/04/03 Javascript
JavaScript保存并运算页面中数字类型变量的写法
2015/07/06 Javascript
Bootstrap树形控件使用方法详解
2016/01/27 Javascript
基于JQuery实现图片上传预览与删除操作
2016/05/24 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
基于layui实现高级搜索(筛选)功能
2019/07/26 Javascript
vue 子组件watch监听不到prop的解决
2020/08/09 Javascript
javascript实现一款好看的秒表计时器
2020/09/05 Javascript
Vue 列表页带参数进详情页的操作(router-link)
2020/11/13 Javascript
Python使用PyGreSQL操作PostgreSQL数据库教程
2014/07/30 Python
Python中无限元素列表的实现方法
2014/08/18 Python
Python并行分布式框架Celery详解
2018/10/15 Python
对python读取CT医学图像的实例详解
2019/01/24 Python
浅析Python与Mongodb数据库之间的操作方法
2019/07/01 Python
使用Python代码实现Linux中的ls遍历目录命令的实例代码
2019/09/07 Python
python如何求100以内的素数
2020/05/27 Python
HTML5超文本标记语言的实现方法
2020/09/24 HTML / CSS
维也纳通行证:Vienna PASS
2019/07/18 全球购物
学校司机岗位职责
2013/11/14 职场文书
中专生自我鉴定范文
2013/12/19 职场文书
平安校园建设方案
2014/05/02 职场文书
大学生活动总结模板
2014/07/02 职场文书
学习型党组织心得体会
2014/09/12 职场文书
自愿离婚协议书范本
2014/09/13 职场文书
公司车辆维修管理制度
2015/08/05 职场文书
多线程Spring通过@Scheduled实现定时任务
2022/05/25 Java/Android